6.使用 std::call_once 实现单例模式

使用 std::call_once 实现单例模式是一个现代且安全的选择,特别是在多线程环境中。相比传统的单例实现方式,它提供了更好的线程安全性和代码简洁性。然而,开发者需要根据具体的需求和环境来选择最合适的实现方法。

在 C++11 及其后续版本中,std::call_once 是一种非常优雅且有效的实现单例模式的方法。

使用 std::call_once 实现单例模式的示例:

#include <iostream>
#include <mutex>

class Singleton {
public:
    static Singleton& getInstance() {
        std::call_once(initInstanceFlag, &Singleton::initInstance);
        return *instance;
    }

private:
    Singleton() {}
    ~Singleton() {}
    
    static void initInstance() {
        instance = new Singleton();
    }
    
    static Singleton* instance;
    static std::once_flag initInstanceFlag;
};

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

int main() {
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();
    
    std::cout << &s1 << " " << &s2 << std::endl; // 应该输出相同的地址
    return 0;
}

      

与传统方式相比的优缺点:

优点:
  1. 线程安全std::call_once 提供了内置的线程安全机制,确保在多线程环境下只会执行一次初始化。这比传统的使用互斥锁的方式更简单和安全。

  2. 惰性初始化:只有在第一次调用 getInstance 时才会初始化单例实例。相较于一些传统方式(如使用 static 变量),它能避免在程序启动时就进行初始化。

  3. 简洁性:代码更简洁,易于理解,减少了手动管理锁的复杂性。

  4. 性能:在多线程环境下,使用 std::call_once 通常比手动加锁性能更好,因为它会避免不必要的锁竞争。

缺点:
  1. C++11 及以上std::call_once 需要 C++11 或更高版本的支持,对于一些较老的编译器不适用。

  2. 静态局部变量的缺陷:如果使用静态局部变量实现单例,可能会遇到静态变量初始化顺序的问题,而 std::call_once 可以避免这种问题。

  3. 初始化时间:虽然实现简单,但在高并发的情况下,std::call_once 可能会导致初始化的延迟,因为只有一个线程可以执行初始化函数,其它线程会被阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值