C++常用设计模式之单例模式
序言
单例模式顾名思义,保证一个类在内存中仅有一个实例化对象,并提供一个可以访问它的全局化接口。实现单例模式必须注意以下几点:
- 单例类只能有一个实例化对象。
- 单例类必须自己提供一个实例化对象。
- 单例类必须提供一个可以访问唯一实例化对象的接口。
单例模式分为懒汉式和饿汉式两种实现方式。
懒汉单例模式
懒汉,顾名思义,不到万不得已就不会去实例化类,也就是说第一次用到类实例的时候才会去实例化一个对象。在访问量较小,甚至可能不会去访问的情况下,采用懒汉实现,以时间换空间。
非线程安全的懒汉单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
class SingleMan { public: static SingleMan *getInstance(); ~SingleMan(){}
private: SingleMan(){} SingleMan(const SingleMan& man) = delete; SingleMan& operator=(const SingleMan& man) = delete;
static SingleMan* m_singleMan; }; SingleMan *SingleMan::m_singleMan = nullptr;
SingleMan *SingleMan::getInstance() { if(m_singleMan == nullptr) { m_singleMan = new SingleMan(); } return m_m_singleMan; }
|
非线程安全的懒汉单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class SingleMan { public: static SingleMan *getInstance(); ~SingleMan(){}
private: SingleMan(){} SingleMan(const SingleMan& man) = delete; SingleMan& operator=(const SingleMan& man) = delete;
static SingleMan* m_singleMan;
std::mutex m_lock; }; SingleMan *SingleMan::m_singleMan = nullptr;
SingleMan *SingleMan::getInstance() { if(m_singleMan == nullptr) { m_lock.lock(); if(m_singleMan == nullptr) { m_singleMan = new SingleMan(); } m_lock.unlock(); } return m_m_singleMan; }
|
返回一个reference指向local static对象
这种单例模式实现方式多线程可能存在不确定性:任何一种non-const static 对象,不论它是local还是non-local,在多线程环境下”等待某事发生“都会有麻烦。
解决办法:在程序的单线程启动阶段手工调用所有reference-returing函数。
下面这种实现方式的好处就是你不需要去关心实例的释放,因为static修饰的变量生命周期和程序一样长。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class SingleMan { public: static SingleMan& getInstance();
private: SingleMan(){} SingleMan(const SingleMan& man) = delete; SingleMan& operator=(const SingleMan& man) = delete;
};
SingleMan& SingleMan::getInstance() { static SingleMan singleMan; return singleMan; }
|
饿汉单例模式
饿汉模式,在访问量较大,或者访问线程较多时,采用饿汉实现,可以实现更好的性能。这是一种空间换时间的策略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class SingleMan { public: static SingleMan* getInstance(); private: SingleMan(){} SingleMan(const SingleMan& man) = delete; SingleMan& operator=(const SingleMan& man) = delete; static SingleMan* m_singleMan; }; SingleMan* SingleMan::m_singleMan = new SingleMan(); SingleMan* SingleMan::getInstance() { return m_singleMan; }
|
UML类图:
