C++ 中实现单例模式有多种方式。单例模式确保一个类只有一个实例,并且提供全局访问该实例的方式,保证类只有一个实例,并提供全局访问点。在程序生命周期中实例只创建一次,节省内存。

1、懒汉式(线程不安全)

懒汉式即按需创建实例,在第一次使用时才会创建。最简单的实现如下,但这种方式在多线程环境下可能不安全。

#include <iostream>

class Singleton {
private:
    static Singleton* instance;  // 唯一实例指针
    Singleton() {}  // 私有构造函数,防止外部直接创建对象

public:
    // 获取唯一实例的函数
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }

    // 示例方法
    void showMessage() {
        std::cout << "Singleton Instance" << std::endl;
    }
};

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

int main() {
    // 获取单例实例并调用方法
    Singleton* singleton = Singleton::getInstance();
    singleton->showMessage();
    
    return 0;
}

2、 线程安全的懒汉式(加锁)

为了确保在多线程环境下的安全,我们可以使用 mutex 来保证线程安全。

#include <iostream>
#include <mutex>

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

public:
    // 获取唯一实例的函数
    static Singleton* getInstance() {
        if (instance == nullptr) {
            std::lock_guard<std::mutex> guard(mtx);  // 加锁
            if (instance == nullptr) {  // 双重检查
                instance = new Singleton();
            }
        }
        return instance;
    }

    // 示例方法
    void showMessage() {
        std::cout << "Singleton Instance" << std::endl;
    }
};

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

int main() {
    // 获取单例实例并调用方法
    Singleton* singleton = Singleton::getInstance();
    singleton->showMessage();
    
    return 0;
}

3、饿汉式(线程安全)

饿汉式在程序开始时就创建单例实例,因此在多线程环境中天然安全,避免了懒汉式的锁机制。

#include <iostream>

class Singleton {
private:
    Singleton() {}  // 私有构造函数

public:
    // 静态实例,程序开始时就创建
    static Singleton& getInstance() {
        static Singleton instance;  // C++11 的局部静态变量,线程安全
        return instance;
    }

    // 示例方法
    void showMessage() {
        std::cout << "Singleton Instance" << std::endl;
    }
};

int main() {
    // 获取单例实例并调用方法
    Singleton& singleton = Singleton::getInstance();
    singleton.showMessage();
    
    return 0;
}