C++设计模式----单例设计模式

单例模式是设计模式中最简单也最常用的模式之一。它的核心思想是:确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。

无论是哪种单例,都必须遵循以下两个关键原则:

  1. 私有化构造函数: 将构造函数声明为 private,防止外部直接使用 new 或直接创建对象。

  2. 禁用拷贝/赋值: 禁用拷贝构造函数和赋值运算符(使用 = delete),确保实例的唯一性

一、饿汉单例模式

原理:_utils_instance 被声明为类的 static 成员,并在类外部定义时被初始化。

静态成员在程序启动时(main 函数执行之前)就会被创建。

特点:

1.线程安全:实例是在主线程启动之前完成初始化的,不存在多线程竞争问题。
2.预先加载: 只要程序启动,无论用不用得到,实例都会被创建。
3.优点:实现简单、天生线程安全,运行速度快。
4.缺点:浪费资源当单例对象很大,且在程序运行中很晚才会被用到,会造成不必要的资源占用。

代码实现:

class Utils1{

public:
    static Utils1* getUtilsInstance()
    {
        return &_utils_instance;
    }
    void print() const{
        std::cout << "print() method" << std::endl;
    }

private:
    Utils1(){}
    // 禁用拷贝构造函数和赋值运算符,确保单例的唯一性
    Utils1(const Utils1&) = delete;
    Utils1& operator=(const Utils1&) = delete;
private:
    static Utils1 _utils_instance;

};
Utils1 Utils1::_utils_instance;

二、双重检查锁定懒汉模式

原理:实例 _utils_instance 初始化为 nullptr,仅在第一次调用getUtils2Instance() 时才创建。使用两个 if 检查,只有在实例尚未创建时才进行昂贵的加锁操作,最大限度地减少了锁的开销,提高了多线程环境下的访问效率。

特点:

1.线程安全条件线程安全: 必须配合 std::atomic / 内存屏障,否则在多线程下存在风险。
2.加载时机延迟加载:。 真正需要时才创建实例,节省启动资源。
3.优点:避免了不必要的资源浪费,并且在实例创建后,访问速度快(无需加锁)。
4.缺点:实现复杂,容易出错,需要深入理解 C++ 内存模型。

代码实现:

class Utils2{
public:
    static Utils2 *getUtils2Instance()
    {
        if(_utils_instance == nullptr)
        {
            // 锁在if里面。需使用锁加if双重判断。即当多个线程同时进行到了if里面。
            // 锁在if外面,单线程使用时候比较重
            std::lock_guard<std::mutex> lock(mtx);
            if(_utils_instance == nullptr)
            {
                _utils_instance = new Utils2();
            }
        }
        return _utils_instance;
    }
private:
    Utils2(){};
    // 禁用拷贝构造函数和赋值运算符,确保单例的唯一性
    Utils2(const Utils2&) = delete;
    Utils2& operator=(const Utils2&) = delete;
private:
    static std::mutex mtx;
    static Utils2* _utils_instance;

};
// 静态成员初始化
std::mutex Utils2::mtx;
Utils2* Utils2::_utils_instance = nullptr; // 初始化为 nullptr

三、局部静态变量懒汉模式 (推荐)

原理:instancegetInstance() 函数内的局部静态变量C++11 标准保证: 如果多线程同时尝试初始化一个局部静态变量,只会有一个线程能够完成初始化。实例的创建被推迟到函数第一次被调用时,同时由编译器确保了线程安全。

特点:

1.线程安全完全线程安全: 由 C++ 标准保证,无需手动加锁。
2.加载时机延迟加载:真正需要时才创建实例。
3.优点:简洁优雅线程安全,延迟加载。 是现代 C++ 中实现单例模式的最佳实践 
class Utils3{
public:
    static Utils3& getInstance() 
    {
        // C++ 标准保证了局部静态变量的初始化是线程安全的
        static Utils3 instance; 
        return instance;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值