一、单例模式
单例模式:一种典型的设计模式。
应用场景:
一个类只能实例化一个对象,向外提供统一访问接口的场景。
作用:
对资源进行统一管理,以及避免数据在不同对象中出现不同的体现。
两种实现:饿汉模式&懒汉模式
二、饿汉模式
1.特点
资源静态化。
在程序初始化阶段,完成对象的实例化。
以空间换时间的思想,在使用的时候就可以直接使用。
优点:
在构造对象时,不需要考虑线程安全问题。
缺点:
初始化速度慢。
2.实现关键
1)如何在程序初始化阶段完成对象的实例化
解决方法:在类中定义唯一的对象,且用static修饰对象
2)如何让一个类只能有一个对象
解决方法:私有化构造函数
3.代码实现
#include<iostream> class Singleton { private: int _data; static Singleton _eton; Singleton () : _data(0) {} public: static Singleton *GetInstance() { return &_eton; } int *GetData() { return &_data; } }; Singleton Singleton::_eton; int main() { std::cout << Singleton::GetInstance() -> GetData() << std::endl; return 0; }
三、懒汉模式
1.特点
对象在访问使用的时候才去实例化。
一种延迟加载的思想,用的时候再去加载,节省资源。
优点:
初始化速度快。
缺点:
在构造对象时,需要考虑线程安全问题。
2.实现关键
1)如何在访问使用的时候采取实例化对象
解决方法:在类中定义唯一的对象指针,且用static修饰
2)如何让一个类只能有一个对象
解决方法:私有化构造函数
总结:
1.定义静态对象指针;
2.构造函数私有化;
3.加锁保护对象构造过程;
4.double check提高效率;
5.volatile关键字修饰,防止编译器过度优化。
3.代码实现
#include<iostream> #include<mutex> class Singleton { private: int _data; /*volatile*/static Singleton *_eton;//c语言实现时,需要加上volatile关键字,保持_eton内存可见性,防止编译器过度优化 static std::mutex _mutex; Singleton() {} public: static Singleton *GetInstance(){ if (_eton == NULL) {//双层检测,降低锁冲突概率 _mutex.lock();//加锁,确保线程安全 if (_eton == NULL) { _eton = new Singleton(); } _mutex.unlock(); } return _eton; } int *GetData() { return &_data; } }; Singleton* Singleton::_eton = NULL; std::mutex Singleton::_mutex; int main() { std::cout << Singleton::GetInstance() -> GetData() << std::endl; return 0; }