C++单例模式实现
Posted striver深度思考
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++单例模式实现相关的知识,希望对你有一定的参考价值。
class CSingleton
{
private:
CSingleton();
CSingleton(const CSingleton &);
CSingleton& operator = (const CSingleton &);
public:
static CSingleton *GetInstance();
static CSingleton *_instance;
};
最为核心的是GetInstance()函数,在单线程下,实现是:
CSingleton* CSingleton::_instance = NULL;
CSingleton* CSingleton::GetInstance()
{
if(_instance == NULL)
{
_instance = new CSingleton();
}
return _instance;
}
CSingleton* CSingleton::GetInstance()
{
lock();
if(_instance == NULL)
{
_instance = new CSingleton();
}
unlock();
return _instance;
}
CSingleton* CSingleton::GetInstance()
{
if(_instance == NULL)
{
lock();
if(_instance == NULL)
{
_instance = new CSingleton();
}
unlock();
}
return _instance;
}
但是这样完美了吗?这段代码看起来没有问题,当函数返回时,_instance总是指向一个有效对象。为lock和unlock又解决了多线程竞争的问题。
但是实际上这个代码也有问题。问题的来源是CPU的乱序执行。C++里,new包含了两个步骤:
- 1. 分配内存
- 2. 调用构造函数。
这时, _instance = new CSingleton()就包含了三步:
- 1. 分配内存
- 2. 调用构造函数
CSingleton* CSingleton::GetInstance()
{
if(_instance == NULL)
{
lock();
if(_instance == NULL)
{
CSingleton * temp = new CSingleton();
barrier(); //不同的平台不一样。
_instance = temp;
}
unlock();
}
return _instance;
}
由于barrier的存在,对象的构造一定在barrier之前完成,因此,当_instance被赋值时对象总是构造好的。如此就实现了多线程环境下的单例模式。
class Singleton
{
private:
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* GetInstance(){
static Singleton instance;
return &instance;
}
};
联系方式:striverx@qq.com, striversx@gmail.com
以上是关于C++单例模式实现的主要内容,如果未能解决你的问题,请参考以下文章