单例模式通过私有构造函数、静态实例和全局访问点确保类唯一实例;2. 多线程下需保证初始化线程安全,早期用双重检查锁定配合mutex;3. C++11后推荐使用局部静态变量实现,因标准保证其初始化线程安全且无需显式加锁;4. 该方法简洁高效,避免内存泄漏,优于智能指针加锁方案。

单例模式确保一个类只有一个实例,并提供全局访问点。在C++中,尤其是在多线程环境下,实现线程安全的单例模式需要特别注意初始化时的竞争条件。
基本单例结构
单例的核心是私有构造函数、静态实例指针和公共的获取实例方法。早期实现常使用懒加载配合锁来保证线程安全。
#include <iostream>
#include <mutex>
<p>class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;</p><pre class='brush:php;toolbar:false;'>// 私有构造函数
Singleton() = default;public: // 删除拷贝构造和赋值 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
void doSomething() {
std::cout << "Singleton working...\n";
}};
立即学习“C++免费学习笔记(深入)”;
// 静态成员定义 Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx;
这种方式使用双重检查锁定(Double-Checked Locking),避免每次调用都加锁。但需注意内存屏障问题,在C++11之后配合std::atomic可更安全。
C++11后的推荐方式:局部静态变量
C++11标准规定,函数内的局部静态变量初始化是线程安全的。利用这一特性,可以写出更简洁且高效的单例。
#include <iostream>
<p>class Singleton {
private:
Singleton() = default;</p><p>public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;</p><pre class='brush:php;toolbar:false;'>static Singleton& getInstance() {
static Singleton instance; // 局部静态变量,线程安全
return instance;
}
void doSomething() {
std::cout << "Singleton working safely in threads.\n";
}};
这种实现无需显式加锁,编译器会自动生成必要的同步代码。它也避免了动态内存管理,减少内存泄漏风险。
使用智能指针管理实例(可选)
如果仍希望控制对象生命周期或使用堆分配,可以用智能指针结合互斥量:
#include <iostream>
#include <memory>
#include <mutex>
<p>class Singleton {
private:
static std::unique_ptr<Singleton> instance;
static std::mutex mtx;</p><pre class='brush:php;toolbar:false;'>Singleton() = default;public: Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;
static Singleton& getInstance() {
std::lock_guard<std::mutex> lock(mtx);
if (!instance) {
instance = std::unique_ptr<Singleton>(new Singleton());
}
return *instance;
}
void doSomething() {
std::cout << "Using unique_ptr for singleton.\n";
}};
虽然可行,但相比局部静态变量方式更复杂,性能略低,一般不推荐除非有特殊需求。
总结:C++中最简单且线程安全的单例实现是使用函数内静态对象。它简洁、高效、由语言标准保障线程安全。基本上就这些,不需要过度设计。










