设计模式书上是这么实现单例模式的:
定义如下: class CSingleton { //其他成员 public: static CSingleton* GetInstance() { if ( m_pInstance == NULL ) //判断是否第一次调用 m_pInstance = new CSingleton(); return m_pInstance; } private: CSingleton(){}; static CSingleton * m_pInstance; };
但是有个问题,就是存在个问题:
1、容易造成内存泄漏和不能正确析构执行
原因,系统不知道什么时候可以删除m_pInstance这个指针所指向的对象。
解决办法:
a、自己来删除,delete掉。
b、定义一个static的对象而不是指针:具体实现参考如下:
class CSingleton { //其他成员 public: static Singleton &GetInstance() { static Singleton instance; return instance; } private: Singleton() {}; };
这也存在一个小问题:
使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。
但使用此种方法也会出现问题,当如下方法使用单例时问题来了,
Singleton singleton = Singleton :: GetInstance();
这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。
最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,我们可以将GetInstance()函数返回一个指针而不是返回一个引用,函数的代码改为如下:
static Singleton *GetInstance()
{
static Singleton instance;
return &instance;
}
也可以让编译器来干:重载 = 操作符为private,新的单例类如下:
class Singleton
{
//其他成员
public:
static Singleton &GetInstance()
{
static Singleton instance;
return instance;
}
private:
Singleton() {};
Singleton(const Singleton);
Singleton & operate = (const Singleton&);
};
关于Singleton(const Singleton); 和 Singleton & operate = (const Singleton&); 函数,需要声明成私用的,并且只声明不实现。这样,如果用上面的方式来使用单例时,不管是在友元类中还是其他的,编译器都是报错。
不知道这样的单例类是否还会有问题,但在程序中这样子使用已经基本没有问题了。
(出处:http://snailbing.blogbus.com/logs/45398975.html)
优化Singleton类,使之适用于单线程应用
Singleton使用操作符new为唯一实例分配存储空间。因为new操作符是线程安全的,在多线程应用中你可以使用此设计模板,但是有一个缺陷:就是在应用程序终止之前必须手工用delete摧毁实例。否则,不仅导致内存溢出,还要造成不可预测的行为,因为Singleton的析构函数将根本不会被调用。而通过使用本地静态实例代替动态实例,单线程应用可以很容易避免这个问题。下面是与上面的GetInstance()稍有不同的实现,这个实现专门用于单线程应用:
CSingleton* CSingleton :: GetInstance()
{
static CSingleton inst;
return &inst;
}
本地静态对象实例inst是第一次调用GetInstance()时被构造,一直保持活动状态直到应用程序终止,指针m_pInstance变得多余并且可以从类定义中删除掉,与动态分配对象不同,静态对象当应用程序终止时被自动销毁掉,所以就不必再手动销毁实例了。
(出处:http://blog.csdn.net/pingnanlee/archive/2009/04/20/4094313.aspx)
以上内容大部分是别人的总结的东西,转载学习下。