📜  单例 C++ (1)

📅  最后修改于: 2023-12-03 15:22:48.892000             🧑  作者: Mango

单例 C++

在软件开发中,单例设计模式是一种创建型设计模式。通过该模式可以保证一个类只有一个实例存在,并且提供一个全局访问点。

实现方式

在 C++ 中,实现单例设计模式有多种方式,示例代码如下:

饿汉式单例

饿汉式单例指的是在程序运行之前就已经创建好该实例,代码如下:

// 在类加载时即创建单例对象
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
private:
    Singleton() {} // 禁止外部构造函数实例化
    Singleton(const Singleton&) = delete; // 禁止外部拷贝构造实例化
    Singleton& operator=(const Singleton&) = delete; // 禁止外部赋值构造实例化
};
懒汉式单例

懒汉式单例指的是只有当第一次请求该实例时才会创建该实例,代码如下:

// 在第一次使用时才创建单例对象
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton* instance;
        if (!instance) {
            instance = new Singleton;
        }
        return *instance;
    }
private:
    Singleton() {} // 禁止外部构造函数实例化
    Singleton(const Singleton&) = delete; // 禁止外部拷贝构造实例化
    Singleton& operator=(const Singleton&) = delete; // 禁止外部赋值构造实例化
};
双检锁/双重校验锁

双检锁指的是在实例不存在时加锁,避免多线程下造成的创建多个实例的问题,代码如下:

// 双检锁/双重校验锁
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton* instance;
        if (!instance) {
            std::lock_guard<std::mutex> lock(mutex_);
            if (!instance) {
                instance = new Singleton;
            }
        }
        return *instance;
    }
private:
    Singleton() {} // 禁止外部构造函数实例化
    Singleton(const Singleton&) = delete; // 禁止外部拷贝构造实例化
    Singleton& operator=(const Singleton&) = delete; // 禁止外部赋值构造实例化
    
    static std::mutex mutex_;
};
std::mutex Singleton::mutex_;
Meyers单例

Meyers单例是一种在 C++11 规范之后新增的函数级单例实现方式,其特点是在程序运行时第一次调用函数时进行单例对象的创建。

class Singleton {
private:
    Singleton() {} // 私有化默认构造函数
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
};
使用范例
int main() {
    Singleton& instance1 = Singleton::getInstance();
    Singleton& instance2 = Singleton::getInstance();

    if (&instance1 == &instance2) {
        std::cout << "单例对象确保了唯一性" << std::endl;
    }
    return 0;
}
总结

通过以上几种实现方式,我们可以确保在程序运行过程中只有一个单例实例存在,从而能够避免全局变量所带来的种种问题。