C++单例模式的实现方式

C++11以前不同的平台下有不同的内存序实现方式,不好处理,本文不做探讨。

本文只总结C++11以后的实现方式。

1 单例模式(饿汉)

程序启动即初始化。最简单的局部静态对象,注意需要隐藏构造和析构,对拷贝控制成员需要删除。

class A {
private:
    A() = default;
    ~A() = default;

    A(A&& rv) = delete;
    A(const A& v) = delete;
    A& operator=(A&& rv) = delete;
    A& operator=(const A& v) = delete;

public:
    static A& getInstance() {
        static A a;
        return a;
    }
};

2 单例模式(懒汉)

class A {
private:
    A() = default;
    ~A() = default;

    A(A&& rv) = delete;
    A(const A& v) = delete;
    A& operator=(A&& rv) = delete;
    A& operator=(const A& v) = delete;

public:
    static A& getInstance() {
        auto tmp = s_instance.load(std::memory_order_acquire); // 和release搭配使用,保证后面对内存的读写操作不重排到前面
        if (!tmp) {
            std::lock_guard<std::mutex> lock(s_mutex);
            tmp = s_instance.load(std::memory_order_relaxed); // 已经在锁内了,使用最宽松的内存序即可
            if (!tmp) {
                tmp = new A();
                s_instance.store(tmp, std::memory_order_release); // 保证A的构造一定在前面完成
            }
        }
        return *tmp;
    }

    static void destroyInstance() {
        std::lock_guard<std::mutex> lock(s_mutex);
        auto tmp = s_instance.exchange(nullptr, std::memory_order_acq_rel);
        if (tmp) {
            delete tmp;
        }
    }

private:
    static std::atomic<A*> s_instance;
    static std::mutex s_mutex;
};

std::atomic<A*> A::s_instance{nullptr};
std::mutex A::s_mutex;

1 单例模板

template <typename T>
class Singleton {
protected: // 构造析构需要让派生类看见
    Singleton() = default;
    virtual ~Singleton() = default;

    Singleton(Singleton && rv) = delete;
    Singleton(const Singleton & v) = delete;
    Singleton & operator=(Singleton && rv) = delete;
    Singleton & operator=(const Singleton & v) = delete;

public:
    static T & getInstance() {
        static T a;
        return a;
    }

    int n = 5;
};

#define SINGLETON_DECLARE(Class) \
private: \
    friend class Singleton<Class>; \
    Class() = default; \
    ~Class() = default; \
    Class(Class && rv) = delete; \
    Class(const Class & v) = delete; \
    Class & operator=(Class && rv) = delete; \
    Class & operator=(const Class & v) = delete;

class A : public Singleton<A> {
    SINGLETON_DECLARE(A)
public:
    int test() {
        return n;
    }
};

int main()
{
    int b2 = A::getInstance().n;
    return 0;
}
posted @ 2026-01-12 19:48  卡卡什么卡  阅读(1)  评论(0)    收藏  举报