单例模式,是一种类的设计模式,采用单例模式设计的类,只允许有一个实例。
为什么要采用单例模式:
1、有些对象在程序的整个声明周期中,为了保证数据的正确性,只允许有一个实例。
2、节省资源
3、满足“低耦合”的设计
单例模式的实现:
单例模式有两种实现方式:懒汉模式、饿汉模式
懒汉模式:
//////////////////////////////////////////////////////////
//懒汉模式
class Signletom
{
public:
static Signletom* GetInstance()
{
static mutex _mtx; //锁子
if (_sInstance == NULL)//优化:双重检查,避免过多的加锁解锁,提高效率
{
//_mtx. lock();
lock_guard<mutex> lock(_mtx); //加锁,保证线程安全
if (_sInstance == NULL)
{
//_sInstance = new Signletom(); //new抛异常的化,可能会死锁 可以改用lock_guard, 它采用RAII,类似智能指针,也就是:构造加锁,析构解锁
Signletom *tmp = new Signletom();
MemoryBarrier(); //内存栅栏:作用:防止编译器的指令优化 (分配空间、构造函数、赋值 这三部必须严格按顺序进行)
_sInstance = tmp;
}
}//_mtx.unlock();
return _sInstance;
}
void Print()
{
cout << _a << endl;
}
protected:
Signletom() //构造函数写在里面
:_a(0)
{}
Signletom(const Signletom*); //拷贝构造也写在里面,防止被调用
Signletom& operator=(const Signletom&); //赋值操作符重载同上
protected:
int _a;
static Signletom *_sInstance;
};
Signletom* Signletom::_sInstance = NULL;饿汉模式:
//////////////////////////////////////////////////////////
//饿汉模式
class SignletomHungry
{
public:
static SignletomHungry* GetInstance()
{
assert(_sInstance);
return _sInstance;
}
void Print()
{
cout << _a << endl;
}
protected:
SignletomHungry() //构造函数写在里面
:_a(0)
{}
SignletomHungry(const SignletomHungry*); //拷贝构造也写在里面,防止被调用
SignletomHungry& operator=(const SignletomHungry&); //赋值操作符重载同上
protected:
int _a;
static SignletomHungry *_sInstance;
};
//静态 和 全局的初始化是在main之前,这时只有一个主线程,因此是线程安全的
SignletomHungry* SignletomHungry::_sInstance = new SignletomHungry();
















