我如何验证给定类的每个实例都被应用程序终止破坏了?
Posted
技术标签:
【中文标题】我如何验证给定类的每个实例都被应用程序终止破坏了?【英文标题】:How might I verify that every instance of a given class is destructed by application termination? 【发布时间】:2012-11-20 18:53:42 【问题描述】:我编写了一个简单的DBResourceMonitor
类,供一组数据库类使用。当我的一个数据库类的实例被创建时,它会注册自己,当被销毁时,它会使用DBResourceMonitor
的单例实例注销自己。当应用程序终止时,DBResrouceMonitor
的全局实例被销毁,它会检查以确保它所监视的任何类都没有剩余的已注册实例(即,对于每个注册,都会调用一个取消注册),并发出如果不匹配,则为 TRACE 输出和 ASSERT。
这一切都很好......直到我将这些数据库对象中的几个作为我的全局应用程序对象的成员。因此,全局应用程序对象和DBResourceMonitor
都是全局单例,应用程序最先被构造,因此最后被销毁,因此当DBResrouceMonitor
被销毁时,应用程序对象的成员有尚未注销,因此它会引发错误,指示存在不匹配的注册/注销调用。
据我所知,没有办法确保DBResrouceMonitor
在应用程序对象之前构建(因此在之后被销毁)。
这是正确的吗?有没有聪明的方法解决这个问题,或者重新考虑上面的方法,以便我仍然可以跟踪在最终线程终止之前是否所有事情都得到了处理?
【问题讨论】:
看看 Schwartz Counters(又名 Nifty Counters) 【参考方案1】:您需要将对这些对象的引用存储在 Singleton 的集合属性中,而不是让对象注册/注销它们自己。所以不要这样做:
var x = new MyDBObject();
你会使用这样的工厂模式:
var x = DBResourceMonitor.GetDBObject();
在 DBResourceMonitor 的某个地方,您可以管理 MyDBObjects 的集合
MyDBObject GetDBObject()
//construct and save a MyDBObject or retrieve one from a list.
【讨论】:
好主意。似乎这可能是要走的路。【参考方案2】:您可以让数据库对象与资源监视器相同,方法是在其构造函数中“注册”数据库对象,并在(虚拟)析构函数中“取消注册”它。这样您就可以只创建对象而不必担心单例或额外的监视器类。对象的集合当然是这个基类中的一个私有静态成员,在您使用多线程的情况下可能会受到保护。
我也会使用std::unique_ptr
代替原始指针,或者可能使用std::shared_ptr
。
【讨论】:
以上是关于我如何验证给定类的每个实例都被应用程序终止破坏了?的主要内容,如果未能解决你的问题,请参考以下文章