应该何时使用单例模式?
你需要系统中只有唯一一个实例存在的类的全局变量的时候才使用单例。
单例模式应具有的特点
越小越好,越简单越好,线程安全,内存不泄露
参考
C++ 单例模式总结与剖析,C++实现单例模式(包括采用C++11中的智能指针)
常遇到的错误示例
class CSingleton
{
private:
CSingleton(){ cout << "单例对象创建!" << endl; };
CSingleton(const CSingleton &);
CSingleton& operator=(const CSingleton &);
~CSingleton(){ delete myInstance; cout << "单例对象销毁!" << endl; };
static CSingleton *myInstance;
public:
static CSingleton* getInstance()
{
return myInstance;
}
static void releaseInstance()
{
delete myInstance;
}
};
CSingleton * CSingleton::myInstance=new CSingleton();
int main() {
CSingleton *ct1 = CSingleton::getInstance();
CSingleton *ct2 = CSingleton::getInstance();
CSingleton *ct3 = CSingleton::getInstance();
}
运行结果: 可见创建的单例对象并没有执行析构函数,也就没有正确执行delete,这样就造成了内存泄露!!! 纠正的方法即添加一个手动释放函数,显式调用析构函数。
下面将几种较为简单的单例模式实现方法(都没有考虑线程安全,可以通过锁来保证线程安全)
对上述错误示例的改进
有两种改进的方法,一种是显示调用析构函数,但是这对使用者来说很不方便。另一种是在类内创建一个内部类,代码如下:
class CSingleton
{
private:
CSingleton(){ cout << "单例对象创建!" << endl; };
CSingleton(const CSingleton &);
CSingleton& operator=(const CSingleton &);
~CSingleton(){ cout << "单例对象销毁!" << endl; };
static CSingleton *myInstance;
public:
static CSingleton* getInstance()
{
return myInstance;
}
private:
class CGarbo{
public:
CGarbo(){};
~CGarbo()
{
if (nullptr != myInstance)
{
delete myInstance;
myInstance = nullptr;
}
}
};
static CGarbo m_garbo;
};
CSingleton * CSingleton::myInstance=new CSingleton();
CSingleton::CGarbo CSingleton::m_garbo;
int main() {
CSingleton *ct1 = CSingleton::getInstance();
CSingleton *ct2 = CSingleton::getInstance();
CSingleton *ct3 = CSingleton::getInstance();
}
智能指针方法
利用智能指针自动析构的特点,应当注意的是,析构函数应为public,否则智能指针调用析构函数的时候会出错。
class CSingleton
{
private:
CSingleton(){ cout << "单例对象创建!" << endl; };
CSingleton(const CSingleton &);
CSingleton& operator=(const CSingleton &);
static shared_ptr<CSingleton> myInstance;
public:
~CSingleton(){ cout << "单例对象销毁!" << endl; };
static shared_ptr<CSingleton> getInstance()
{
if(myInstance == nullptr){
myInstance = shared_ptr<CSingleton>(new CSingleton());
}
return myInstance;
}
};
shared_ptr<CSingleton> CSingleton::myInstance = nullptr;
int main() {
shared_ptr<CSingleton> ct1 = CSingleton::getInstance();
shared_ptr<CSingleton> ct2 = CSingleton::getInstance();
shared_ptr<CSingleton> ct3 = CSingleton::getInstance();
}
运行结果:
|