管理单例析构函数
Managing a singleton destructor
下面的小示例实现了一个我见过很多次的单例模式:
#include <iostream>
class SingletonTest {
private:
SingletonTest() {}
static SingletonTest *instance;
~SingletonTest() {
std::cout << "Destructing!!" << std::endl;
}
public:
static SingletonTest *get_instance() {
if(!instance) instance = new SingletonTest;
return instance;
}
};
SingletonTest *SingletonTest::instance = 0;
int main(int argc, char *argv[]) {
SingletonTest *s = SingletonTest::get_instance();
return 0;
}
这样做的主要问题是,我的单例的析构函数永远不会被调用。
我可以让instance
a (c++0x?)shared_ptr
,它工作得很好——除了它意味着我的析构函数必须是公共的。
我可以添加一个静态的'cleanup'方法,但这会增加用户错误的可能性(例如,忘记调用它)。它也不允许在面对(未处理的)异常时进行适当的清理。
是否有一种通用的策略/模式允许惰性实例化,"自动"调用析构函数,并且仍然允许我将析构函数保持私有?…不完全是一个直接的答案,但是对于一个注释来说太长了——为什么不这样做呢:
class SingletonTest {
private:
SingletonTest() {}
~SingletonTest() {
std::cout << "Destructing!!" << std::endl;
}
public:
static SingletonTest& get_instance() {
static SingletonTest instance;
return instance;
}
};
现在你有一个懒惰的单例,它将在退出时被销毁…它的可重入性不比你的代码差…
您可以编写一个取消初始化的函数,并在对象构造函数中调用atexit()
来注册它。然后,当c++运行时对模块进行反初始化时,它将在main()调用你的反初始化函数之后的某个时刻。这个粗体是存在的,因为您对何时调用它的控制相当松散,这可能导致取消初始化顺序的惨败-要小心。
您总是可以将shared_ptr(或者更合适的是scoped_ptr)加为好友,以允许它访问您的私有析构函数。
注意,还有一个系统atexit()
函数,它可以注册一个函数,以便在应用程序结束时调用。你可以传递一个单例的静态函数,它只对它执行delete instanance;
。
请注意,将将要成为单例的类与它的单例性分开通常是个好主意。特别是在测试和/或当您确实需要双元时。:)
在这里,尽量避免延迟初始化。初始化/创建你的单例,在启动时,以一个良好确定的顺序。这允许它们正确关闭并解决依赖关系,而不会出现意外。(我经历了循环的单身地狱……这比你想象的要容易…
您可以通过传入一个可以访问析构函数的deleter(例如定义为SingletonTest
成员的类)来对shared_ptr
使用私有析构函数。
但是,在销毁单例时需要非常小心,以确保它们在被销毁后不会被使用。为什么不直接使用一个普通的全局变量呢?
如果您将实际执行delete
操作的类声明为友类(让它是shared_ptr<SingletonTest>
或某种默认的删除器),则析构函数可以是私有的。虽然我觉得没有必要把它设为私有
第一个问题是:您是否希望解构单例。销毁单例可能会导致销毁顺序问题;和既然你关闭了,析构函数就不需要维护程序不变量。这大概是你唯一想运行单例模式的析构函数是,如果它管理的资源是系统无法使用的不会像临时文件那样自动清理。否则,它的最好不要调用析构函数
如果您希望调用析构函数,则有两个选项:将单个对象声明为静态局部变量instance
函数,或者使用std::auto_ptr
或类似的东西,而不是一个原始指针,作为指向它的指针。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 单例类析构函数无法清理 (SDL_Quit) MinGW
- 如何析构单例实例,或者为什么以下代码适用于析构函数?
- 便携式C++单例 - 何时调用析构函数
- 单例:为什么不需要删除并且看不到析构函数调试消息
- 为什么在单例类中私有析构函数
- 析构函数调用表单不适当的库
- 具有使用 std::unique_ptr 的私有析构函数的单例
- 扩展具有私有构造函数和析构函数的单例类会给出编译时警告
- c++中,单例类的析构函数被再次调用
- lua绑定的单例类在析构函数中崩溃
- 虚拟析构函数用例
- 称为error的单例析构函数
- 从单例类调用继承类的析构函数
- 管理单例析构函数
- 为什么当我单击控制台上的关闭按钮时没有调用析构函数
- 单例析构函数