单例模式的要点有三个:
1.某个类只能有一个实例。
2.它必须自行创建这个实例。
3.它必须自行向整个系统提供这个实例。
如何实现,对应以下三点:
1.单例模式的类只提供私有的构造函数。
2.类定义中含有一个该类的静态私有对象。
3.该类提供了一个静态的公有的函数,用于创建或获取它本身的静态私有对象。
class CSingleton
{
private:
static CSingleton * m_pInstance;
CSingleton()
{
}
public:
static CSingleton * GetInstance()
{
if(m_pInstance==NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};
这是最简洁的单例模式的表示,但是还有要考虑到最大的问题就是内存泄漏。
因为m_pInstance是私有成员,无法再CSingleton类外delete。一种解决方法是写一个公有的析构函数delete,并在程序结束前调用,但这样析构函数就可以随意被调用,也不合适。
因为类中的静态成员变量,在程序结束的时候,系统会自动调用它的析构函数。
改进方案1:
class CSingleton
{
private:
static CSingleton * m_pInstance;
CSingleton(){}
class CGarbo //它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if(CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGarbo Garbo; //程序结束时系统会自动调用它的析构函数
public:
static CSingleton * GetInstance()
{
if(m_pInstance==NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};
以上方法略微复杂,还有简单的方法:静态局部变量与全局变量共享全局数据区,但静态局部变量只在定义它的函数中可见,利用静态局部变量,在函数执行完后不会被销毁的原理,可以这样实现:
改进方案2:
class CSingleton
{
private:
CSingleton(){};
CSingleton(const CSingleton &);
CSingleton & operator =(const CSingleton &);
public:
static CSingleton * GetInstance()
{
static CSingleton m_pInstance;
return m_pInstance;
}
};
CSingleton(const CSingleton &)和CSingleton & operator =(const CSingleton &)的私有声明,是为了防止单例被复制。