单例模式
1. 什么是单例模式
单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
定义一个单例类:
- 私有化它的构造函数,以防止外界创建单例类的对象;
- 使用类的私有静态指针变量指向类的唯一实例;
- 使用一个公有的静态方法获取该实例。

2.懒汉版
static Singleton* getInstance() {
if(instance == NULL) {
Lock lock; // 基于作用域的加锁,超出作用域,自动调用析构函数解锁
if(instance == NULL) {
instance = new Singleton();
}
}
return instance;
}
instance = new Singleton()可以分为3步:
1.分配一块空间
2.调用构造器构造对象
3.这块空间赋值给instance
意外情况:
正常的123执行顺序变成了132,线程执行到13时时间片结束,挂起,下一次另一个线程执行到
if(instance == NULL)
此时不为空,返回instace,但是这个instance还没有构造出来,导致出错。
C++11中的atomic类的默认memory_order_seq_cst保证了3、6行代码的正确同步
atomic<Widget*> Widget::pInstance{ nullptr };
Widget* Widget::Instance() {
if (pInstance == nullptr) {
lock_guard<mutex> lock{ mutW };
if (pInstance == nullptr) {
pInstance = new Widget();
}
}
return pInstance;
}
Best of All:
C++11规定了local static在多线程条件下的初始化行为,要求编译器保证了内部静态变量的线程安全性。在C++11标准下,《Effective C++》提出了一种更优雅的单例模式实现,使用函数内的 local static 对象。这样,只有当第一次访问getInstance()方法时才创建实例。这种方法也被称为Meyers' Singleton。C++0x之后该实现是线程安全的,C++0x之前仍需加锁。
// version 1.2
class Singleton
{
private:
Singleton() { };
~Singleton() { };
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
};
3. 饿汉版(Eager Singleton)
饿汉版(Eager Singleton):指单例实例在程序运行时被立即执行初始化
// version 1.3
class Singleton
{
private:
static Singleton instance;
private:
Singleton();
~Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton& getInstance() {
return instance;
}
}
// initialize defaultly
Singleton Singleton::instance;
有些内容转载自知乎:
C++ 单例模式
https://zhuanlan.zhihu.com/p/37469260
浙公网安备 33010602011771号