cpp-设计模式之单例模式
cpp-设计模式之单例模式
设计模式之单例模式
单例模式简介
单例模式是最简单的模式之一,其目的为保证一个类只有一个实例,并提供一个访问它的全局节点.
懒汉式(Lazy Singleton)
懒汉式是最基本的单例模式,单例实例会在第一次被使用时才进行初始化,称之为延迟初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
class Singleton{
public:
static Singleton * getInstance(){
if(pInstance == nullptr){
pInstance = new Singleton();
std::cout << "创建唯一实例" << std::endl;
}
return pInstance;
};
private:
Singleton(){}; //构造函数设计成私有的
static Singleton* pInstance;
};
Singleton* Singleton::pInstance = nullptr;
int main()
{
Singleton* obj = Singleton::getInstance();
return 0;
}
懒汉式会存在问题:
线程不安全的问题. 比如两个线程同时调用了 getInstance,恰巧此时 pInstance 都为 nullptr,那么就会调用两次 new,最简单的方法是加锁
存在内存泄漏问题. 有两种解决方法,一种是使用共享指针,另外一种是使用静态的嵌套类对象
改进版懒汉式:
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
31
32
#include <iostream>
#include <memory>
#include <mutex>
class Singleton{
public:
static std::shared_ptr<Singleton> getInstance(){
if(pInstance == nullptr){
// doble checked lock
std::lock_guard<std::mutex> lock(mutex);
if(pInstance == nullptr){
// pInstance = new Singleton();
pInstance = std::shared_ptr<Singleton>(new Singleton);
std::cout << "创建唯一实例" << std::endl;
}
}
return pInstance;
};
private:
Singleton(){}; //构造函数设计成私有的
static std::mutex mutex;
static std::shared_ptr<Singleton> pInstance;
};
std::shared_ptr<Singleton> Singleton::pInstance = nullptr;
std::mutex Singleton::mutex;
int main()
{
std::shared_ptr<Singleton> obj = Singleton::getInstance();
return 0;
}
其优点是使用 shared_ptr,基于 RAII 思想用对象管理资源,当 shared_ptr 析构时,new 出来的对象也会被析构掉。 双检锁,double check,使用锁保证线程安全,双检:保证只有当智能指针为空的时候,才会加锁检查,避免每次调用 getInstance 的方法都加锁,浪费锁的开销
另外还可以使用 magic static,局部静态变量,这是最推荐的懒汉式实现方法,其思想主要是利用 c++11 的 static 个性,当变量在初始化的时候,并发同时进入声明语句,并发线程将会阻塞等待初始化结束,这就保证了并发线程 在获取静态局部变量的时候一定是初始化过的,所以具有线程安全性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <memory>
#include <mutex>
class Singleton{
public:
static Singleton& getInstance(){
static Singleton pInstance;
return pInstance;
};
private:
Singleton(){
std::cout << "创建单例模式" << std::endl;
}; //构造函数设计成私有的
};
int main()
{
Singleton obj = Singleton::getInstance();
return 0;
}
饿汉式(Eager Singleton)
饿汉式是指单例实例在程序运行时就被立即执行初始化
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
#include <iostream>
#include <memory>
#include <mutex>
class Singleton{
public:
static Singleton& getInstance(){
return pInstance;
};
private:
Singleton(){
std::cout << "创建单例模式" << std::endl;
}; //构造函数设计成私有的
static Singleton pInstance;
};
Singleton Singleton::pInstance;
int main()
{
Singleton obj = Singleton::getInstance();
return 0;
}
参考链接:https://www.jianshu.com/p/b71b26c5165b
本文由作者按照 CC BY 4.0 进行授权