单例模式

设计模式汇总

单例模式

  • 单例模式的关键特点:
    • 唯一实例:类只能有一个实例。
    • 全局访问点:提供一个全局访问点来获取这个唯一实例。

饿汉懒汉

  • 饿汉方式 —— 预先加载。
    1
    2
    3
    4
    5
    6
    7
    8
    template <typename T>
    class Singleton {
    static T data;/*在main函数之间就被实例化。*/
    public:
    static T* GetInstance() {
    return &data;
    }
    };
  • 懒汉方式 —— 延迟加载。
1
2
3
4
5
6
7
8
9
10
11
template <typename T>
class Singleton {
static T* inst;
public:
static T* GetInstance() {
if (inst == NULL) {/*使用的时候才实例化。*/
inst = new T();
}
return inst;
}
};
  • 一般情况下,懒汉方式可以提高我们程序启动的速度,但是懒汉模式可能存在线程安全问题。

懒汉方式实现单例模式(线程不安全)

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

class Singleton {
private:
static Singleton* instance;

// 私有构造函数,防止外部实例化
Singleton() {}

// 删除拷贝构造函数
Singleton(const Singleton&) = delete;

// 删除拷贝赋值运算符
Singleton& operator=(const Singleton&) = delete;

public:
// 静态方法,获取单例实例
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};

// 初始化静态成员变量
Singleton* Singleton::instance = nullptr;

使用锁来保证线程安全

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <mutex>

class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;

// 私有构造函数,防止外部实例化
Singleton() {}

// 删除拷贝构造函数
Singleton(const Singleton&) = delete;

// 删除拷贝赋值运算符
Singleton& operator=(const Singleton&) = delete;

public:
// 静态方法,获取单例实例
static Singleton* getInstance() {
if (instance == nullptr){ //减少锁冲突,提高效率
std::lock_guard<std::mutex> lock(mtx); // 加锁
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
};

// 初始化静态成员变量
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();

if (s1 == s2) {
std::cout << "Singleton works, both variables contain the same instance." << std::endl;
} else {
std::cout << "Singleton failed, variables contain different instances." << std::endl;
}

return 0;
}

局部静态变量保证线程安全

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
33
34
#include <iostream>

class Singleton {
private:
// 私有构造函数,防止外部实例化
Singleton() {}

// 删除拷贝构造函数
Singleton(const Singleton&) = delete;

// 删除拷贝赋值运算符
Singleton& operator=(const Singleton&) = delete;

public:
// 静态方法,获取单例实例
static Singleton& getInstance() {
static Singleton instance; /* 局部静态变量是线程安全的,C++11 保证一个局部静态变量只会被初始化一次,且多个线程不会同时进入静态变量的初始化过程*/
return instance;
}
};

int main() {
Singleton& s1 = Singleton::getInstance();
Singleton& s2 = Singleton::getInstance();

if (&s1 == &s2) {
std::cout << "Singleton works, both variables contain the same instance." << std::endl;
} else {
std::cout << "Singleton failed, variables contain different instances." << std::endl;
}

return 0;
}


单例模式
https://weihehe.top/2024/08/01/设计模式/
作者
weihehe
发布于
2024年8月1日
许可协议