C++单例模式的实现

1. 饿汉式:

使用静态变量的线程安全性。

// 隐藏构造函数是因为防止主程序进行对象的构造
#define SINGLETON_CTOR(x) \
     private:\
            x() = default;\
            x(const x&)=delete;\
            x& operator=(const x&)=delete;\
            ~x()=default;

class SingletonStarve {
SINGLETON_CTOR(SingletonStarve);
public:
    static SingletonStarve& instance() {
        // 静态局部变量会在第一次使用时初始化,多次调用会被编译器忽略,生命周期是程序的运行区间。多线程安全
        // 静态局部变量分配在全局静态数据区(不是堆和栈)
        static SingletonStarve _instance;
        return _instance;
    }
};

int main() {
    // 这里不可写成SingletonStarve singleton = SingletonStarve::instance(),因为会调用赋值函数执行拷贝初始化
    SingletonStarve& singleton = SingletonStarve::instance();
}

2. 懒汉式

2.1 double-check

我们以double-check lock作为基本框架。为了处理此SingletonLazy单例的内存回收,我们使用unique_ptr来在程序结束时析构该对象。

class SingletonLazy {
SINGLETON_CTOR(SingletonLazy);
public:
    static SingletonLazy& instance() {
        // double check
        if (p_instance == nullptr) {
            std::lock_guard<std::mutex> lock(m_lock);
            if (p_instance == nullptr) {
                p_instance.reset(new SingletonLazy);
            }
        }
        // 使用智能指针,建议返回引用
        return *p_instance;
    }

private:
    static std::unique_ptr<SingletonLazy> p_instance;
    static std::mutex m_lock;
};

// 记得初始化这俩静态变量
std::unique_ptr<SingletonLazy>  SingletonLazy::p_instance;
std::mutex SingletonLazy::m_lock;

2.2 无锁——std::call_once

使用call_once来保护一段代码块(只执行一次)

class SingletonLazy {
SINGLETON_CTOR(SingletonLazy);
public:
    static SingletonLazy& instance() {
        static std::once_flag s_flag;
        // 这段代码只会执行一次
        std::call_once(s_flag, [&]() {
            p_instance.reset(new SingletonLazy);
        });
        return *p_instance;
    }

private:
    static std::unique_ptr<SingletonLazy> p_instance;
};

std::unique_ptr<SingletonLazy>  SingletonLazy::p_instance;
posted @   南小小小小乔  阅读(91)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示