静态变量的方式实现的单例类和单例模板

本文深入解析C++11标准下局部静态变量的线程安全初始化特性,探讨其在单例模式实现中的应用。重点介绍了局部静态变量的初始化过程,包括异常处理、并发控制及递归调用的未定义行为,同时提供了线程安全的单例类实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

分析

    在C++11标准中,要求局部静态变量初始化具有线程安全性。描述(在标准草案的6.7节中):

such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.

     标准关于局部静态变量初始化,有这么几点要求:

  1. 变量在代码第一次执行到变量声明的地方时初始化。
  2. 初始化过程中发生异常的话视为未完成初始化,未完成初始化的话,需要下次有代码执行到相同位置时再次初始化。
  3. 在当前线程执行到需要初始化变量的地方时,如果有其他线程正在初始化该变量,则阻塞当前线程,直到初始化完成为止。
  4. 如果初始化过程中发生了对初始化的递归调用,则视为未定义行为。

单例类

因此我们可以很容易实现一个线程安全的单例类:

class Singleton
{
public:
    static Singleton* instance()
    {
        static Singleton ins;
        return &ins;
    }

private:
    Singleton(){}
};

上述单例模式的实现中,在instance函数中声明static的局部变量,因为静态变量在程序中只会分配一次内存,保证了实例的唯一性,并且作为局部变量只有在程序第一次调用的时候才会初始化,也实现了延迟加载,而且因为不是指针变量,在程序结束时会自动回收内存。

 

单例模板

template<typename T>
class Singleton
{
public:
    static T* instance()
    {
        static T ins;
        return &ins;
    }

//如果要让继承类访问,就不要实现此构造函数
private:
    Singleton(){}
};

当我们需要这个单例类模板时,只需要在自己类里通过friend添加为友元即可。

 

demo:

https://github.com/fengxieye/Qt-demo/tree/master/singleton

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值