在实现饿汉式单例模式时, java和c#在类中声明静态私有成员实例并new
在c++中,声明的静态成员如果使用new之后,本想在类析构中delete掉自己,但是在调试时发现此法不可行.因为在析构函数中调用delete会导致,析构函数被递归调用,当调用堆栈满时就会产生异常.
代码如下:
View Code
1 class Singleton 2 { 3 public: 4 ~Singleton() 5 { 6 if(instance) 7 { 8 delete this; 9 instance = NULL; 10 } 11 } 12 13 static Singleton* getInstance() 14 { 15 if(instance == NULL) 16 { 17 instance = new Singleton; 18 } 19 return instance; 20 } 21 22 private: 23 Singleton(){} 24 static Singleton* instance; 25 Singleton(const Singleton&); 26 Singleton& operator=(const Singleton&); 27 } 28 29 Singleton* Singleton::instance = NULL;
尝试第一种方法: 在类中增加一个成员函数Suicide(),那么使用单例类的客户代码要主动调用suicide()否则还是会出现没有释放对象而导致的内存泄漏
View Code
1 class Singleton 2 { 3 public: 4 ~Singleton() 5 { 6 // if(instance) 7 // { 8 // delete this; 9 // instance = NULL; 10 // } 11 } 12 13 static Singleton* getInstance() 14 { 15 if(instance == NULL) 16 { 17 instance = new Singleton; 18 } 19 return instance; 20 } 21 22 void Suicide() 23 { 24 delete instance; 25 instance = NULL; 26 } 27 28 private: 29 Singleton(){} 30 static Singleton* instance; 31 Singleton(const Singleton&); 32 Singleton& operator=(const Singleton&); 33 } 34 35 Singleton* Singleton::instance = NULL;
那么现在仍然没有解决上面的问题.
根据c++语言的特性.变量离开作用域后会自动调用析构函数.从而有了智能指针.
尝试2
使用std中的shared_ptr, 客户端的代码就会修改为对shared_ptr<Singleton> 实例的操作
至此貌似解决了单线程情况下的单例构造.
还有其他的单线程下的单例实现方式吗?
对于C++来说 有,也是最常用的.在类的静态函数中定义一个静态类实例.在程序结束后,该静态实例会被自动析构
class Singleton { public: ~Singleton(){} static Singleton& getInstance() { static Singleton instance; return instance; } private: Singleton(){} Singleton(const Singleton&); Singleton& operator=(const Singleton&); }