单例模式,是一种类的设计模式,采用单例模式设计的类,只允许有一个实例。
为什么要采用单例模式:
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 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;
原文地址:http://zhweizhi.blog.51cto.com/10800691/1842655