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;
}

浙公网安备 33010602011771号