设计模式:单例模式
相信大家面试都逃不开设计模式话题,本节将阐述面试中的最常用的设计模式单例模式,从分类,线程安全,不基于C++11标准的角度与基于C++11标准的角度,有哪些解决
试读章节 · 登录解锁全文
1 小时
C++设计模式之单例模式
0.导语
相信大家面试都逃不开设计模式话题,本节将阐述面试中的最常用的设计模式(单例模式),从分类,线程安全,不基于C++11标准的角度与基于C++11标准的角度,有哪些解决线程安全的单例模式方案,相信认真看完本篇文章,在以后面试中就不用担忧了。
1.众所周知的单例
在一般书籍中或者大家比较是熟知的单例模式是下面这样:
class singleton {
private:
singleton() {}
static singleton *p;
public:
static singleton *instance();
};
singleton *singleton::p = nullptr;
singleton* singleton::instance() {
if (p == nullptr)
p = new singleton();
return p;
}
这是一个非常简单的实现,将构造函数声明为private或protect防止被外部函数实例化,内部有一个静态的类指针保存唯一的实例,实例的实现由一个public方法来实现,该方法返回该类的唯一实例。
当然这个代码只适合在单线程下,当多线程时,是不安全的。考虑两个线程同时首次调用instance方法且同时检测到p是nullptr,则两个线程会同时构造一个实例给p,这将违反了单例的准则。
2.懒汉与饿汉
单例分为两种实现方法:
- 懒汉
- 第一次用到类实例的时候才会去实例化,上述就是懒汉实现。
- 饿汉
- 单例类定义的时候就进行了实例化。
这里也给出饿汉的实现:
class singleton {
private:
singleton() {}
static singleton *p;
public:
static singleton *instance();
};
singleton *singleton::p = new singleton();
singleton* singleton::instance() {
return p;
}
当然这个是线程安全的,对于我们通常阐述的线程不安全,为懒汉模式,下面会阐述懒汉模式的线程安全代码优化。
3.多线程加锁
在C++中加锁有个类实现原理采用RAII,不用手动管理unlock,那就是lock_guard,这里采用其进行加锁。
class singleton {
private:
…