用法:

1. 基础线程不安全版本 懒汉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Singleton {
private:
static Singleton* instance;
Singleton() {} // 私有构造函数

public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};

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

2. 线程安全版本(C++11及以上) 懒汉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <mutex>

class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;
Singleton() {} // 私有构造函数

public:
static Singleton* getInstance() {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};

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

3. Meyer’s Singleton(推荐) 饿汉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton {
private:
Singleton() {} // 私有构造函数

public:
static Singleton& getInstance() {
static Singleton instance; // C++11保证线程安全
return instance;
}

// 禁止拷贝构造和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};

4. 智能指针版本

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
#include <memory>
#include <mutex>

class Singleton {
private:
static std::shared_ptr<Singleton> instance;
static std::mutex mtx;
Singleton() {} // 私有构造函数

public:
static std::shared_ptr<Singleton> getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = std::shared_ptr<Singleton>(new Singleton());
}
}
return instance;
}

// 禁止拷贝构造和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};

// 静态成员初始化
std::shared_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mtx;

5. 模板通用版本

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
#include <mutex>

template<typename T>
class Singleton {
private:
static T* instance;
static std::mutex mtx;

public:
static T* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new T();
}
}
return instance;
}

// 禁止拷贝构造和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};

// 模板静态成员定义
template<typename T>
T* Singleton<T>::instance = nullptr;

template<typename T>
std::mutex Singleton<T>::mtx;

使用示例

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

class MyClass {
private:
int value;
MyClass() : value(0) {} // 私有构造函数
friend class Singleton<MyClass>; // 允许Singleton访问私有构造函数

public:
void setValue(int v) { value = v; }
int getValue() const { return value; }
};

// 使用方式
int main() {
// 使用Meyer's Singleton
auto& singleton = Singleton::getInstance();

// 使用模板版本
auto* myClass = Singleton<MyClass>::getInstance();
myClass->setValue(42);
std::cout << "Value: " << myClass->getValue() << std::endl;

return 0;
}

推荐使用

对于大多数情况,推荐使用 Meyer’s Singleton 实现方式,因为它:

  • 线程安全(C++11标准保证)
  • 自动销毁(RAII)
  • 代码简洁
  • 性能较好(延迟初始化)

还有一种,采用双锁检查机制。

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 <mutex>
#include <atomic>

class Singleton {
private:
static std::atomic<Singleton*> instance;
static std::mutex mtx;
Singleton() {}

public:
static Singleton* getInstance() {
// 第一次检查(无锁)
Singleton* tmp = instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
// 加锁后第二次检查
std::lock_guard<std::mutex> lock(mtx);
tmp = instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
tmp = new Singleton();
instance.store(tmp, std::memory_order_relaxed);
}
}
return tmp;
}

// 禁止拷贝构造和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};

// 静态成员初始化
std::atomic<Singleton*> Singleton::instance{nullptr};
std::mutex Singleton::mtx;