单例模式前面已经说过了,下面说说单例模式的私有静态成员_singleton的释放
如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面所示的代码无法实现这个要求。我们需要一种方法,正常地删除该实例。
可以在程序结束时调用GetInstance并对返回的指针调用delete操作。这样做可以实现功能,但是不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。
一个妥善的方法是让这个类自己知道在合适的时候把自己删除。或者说把删除自己的操作挂在系统中的某个合适的点上,使其在恰当的时候自动被执行。
我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利 用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;class Singleton
{
private:class AutoRelease{public:AutoRelease(){cout << "AutoRelease()" << endl;}~AutoRelease(){if(_pInstance){delete _pInstance;cout << "~AutoRelease()" << endl;}}};
public:static Singleton * getInstance(){if(_pInstance == NULL)_pInstance = new Singleton;return _pInstance;}private:Singleton(){ cout << "Singleton()" << endl;}~Singleton(){ cout << "~Singleton()" << endl;}private:static Singleton * _pInstance;static AutoRelease _autoRelease;
};Singleton * Singleton::_pInstance = getInstance();
Singleton::AutoRelease Singleton::_autoRelease;int main(void)
{Singleton *p1 = Singleton::getInstance();Singleton *p2 = Singleton::getInstance();printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);return 0;
}
执行结果为:
Singleton()
AutoRelease()
p1 = 0x172b010
p2 = 0x172b010
~Singleton()
~AutoRelease()
第二种方法:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using std::cout;
using std::endl;//第二种方法:饿汉式 + atexit函数
class Singleton
{
public:static Singleton * getInstance(){if(_pInstance == NULL){_pInstance = new Singleton;atexit(destroy);}return _pInstance;}static void destroy(){if(_pInstance)delete _pInstance;}private:Singleton(){ cout << "Singleton()" << endl;}~Singleton(){ cout << "~Singleton()" << endl;}private:static Singleton * _pInstance;
};Singleton * Singleton::_pInstance = getInstance();int main(void)
{Singleton *p1 = Singleton::getInstance();Singleton *p2 = Singleton::getInstance();printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);return 0;
}
Singleton()
p1 = 0x245f010
p2 = 0x245f010
~Singleton()
第三种方法:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;//第三种方法: pthread_once函数 + atexit函数
class Singleton
{
public:static Singleton * getInstance(){pthread_once(&_once, init);return _pInstance;}static void init(){_pInstance = new Singleton;atexit(destroy);}static void destroy(){if(_pInstance)delete _pInstance;}private:Singleton(){ cout << "Singleton()" << endl;}~Singleton(){ cout << "~Singleton()" << endl;}private:static Singleton * _pInstance;static pthread_once_t _once;
};Singleton * Singleton::_pInstance = getInstance();
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;int main(void)
{Singleton *p1 = Singleton::getInstance();Singleton *p2 = Singleton::getInstance();printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);return 0;
}
Singleton()
p1 = 0x19d9010
p2 = 0x19d9010
~Singleton()