我写了一个简单的DBResourceMonitor
类,它被一组数据库类使用。当我的一个数据库类的实例被创建时,它会注册自己,当被销毁时,它用DBResourceMonitor
的单例实例注销自己。当应用程序终止时,DBResrouceMonitor
的全局实例将被销毁,这将进行检查以确保其监视的任何类都没有剩余的已注册实例(即,对于每个寄存器,都调用了一个注销器),并在不匹配时发出TRACE输出和ASSERT。
这一切都很好。。。直到我将其中几个数据库对象作为全局应用程序对象的成员。因此,全局应用程序对象和DBResourceMonitor
都是全局单例,并且应用程序是第一个要构建的,因此是最后一个要销毁的,因此当DBResrouceMonitor
被销毁时,应用程序对象的成员尚未注销,因此它抛出一个错误,指示存在不匹配的注册/注销调用。
据我所知,没有办法确保DBResrouceMonitor
在应用程序对象之前构建(因此在之后销毁)。
这是正确的吗?有没有一个聪明的方法来解决这个问题,或者有没有一种方法来重新思考上面的问题,这样我仍然可以跟踪在最后一个线程终止之前是否所有的事情都得到了处理?
您需要将对这些对象的引用存储在singleton的集合属性中,而不是让对象向singleton注册/注销。因此,与其这么做:
var x = new MyDBObject();
你会使用一个工厂模式,比如:
var x = DBResourceMonitor.GetDBObject();
在DBResourceMonitor中的某个地方,您可以管理MyDBObjects 的集合
MyDBObject GetDBObject()
{
//construct and save a MyDBObject or retrieve one from a list.
}
您可以让数据库对象与资源监视器相同,方法是让基类在其构造函数中"注册"数据库对象,并在(虚拟)析构函数中"注销"它。通过这种方式,您可以只创建对象,而不必担心singleton或额外的监视器类。对象的集合当然是这个基类中的私有静态成员,在使用多线程的情况下可能受到保护。
我还将使用std::unique_ptr
而不是原始指针,或者可能使用std::shared_ptr
。