C++如何实现单例模式_C++线程安全的单例模式代码实现

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

单例模式确保一个类只有一个实例,并提供全局访问点。在C++中,尤其是在多线程环境下,实现线程安全的单例模式需要特别注意初始化时的竞争条件。

基本单例结构

单例的核心是私有构造函数、静态实例指针和公共的获取实例方法。早期实现常使用懒加载配合锁来保证线程安全。

#include 
#include 

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

// 私有构造函数
Singleton() = default;

public: // 删除拷贝构造和赋值 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;

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

void doSomething() {
    std::cout << "Singleton working...\n";
}

};

// 静态成员定义 Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx;

这种方式使用双重检查锁定(Double-Checked Locking),避免每次调用都加锁。但需注意内存屏障问题,在C++11之后配合std::atomic可更安全。

C++11后的推荐方式:局部静态变量

C++11标准规定,函数内的局部静态变量初始化是线程安全的。利用这一特性,可以写出更简洁且高效的单例。

#include 

class Singleton { private: Singleton() = default;

public: Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;

static Singleton& getInstance() {
    static Singleton instance; // 局部静态变量,线程安全
    return instance;
}

void doSomething() {
    std::cout << "Singleton working safely in threads.\n";
}

};

这种实现无需显式加锁,编译器会自动生成必要的同步代码。它也避免了动态内存管理,减少内存泄漏风险。

使用智能指针管理实例(可选)

如果仍希望控制对象生命周期或使用堆分配,可以用智能指针结合互斥量:

#include 
#include 
#include 

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

Singleton() = default;

public: Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;

static Singleton& getInstance() {
    std::lock_guard lock(mtx);
    if (!instance) {
        instance = std::unique_ptr(new Singleton());
    }
    return *instance;
}

void doSomething() {
    std::cout << "Using unique_ptr for singleton.\n";
}

};

虽然可行,但相比局部静态变量方式更复杂,性能略低,一般不推荐除非有特殊需求。

总结:C++中最简单且线程安全的单例实现是使用函数内静态对象。它简洁、高效、由语言标准保障线程安全。基本上就这些,不需要过度设计。