单例模式
保证一个类仅有一个实例,并提供一个该实例的全局访问点
版本一
C++
class Singleton1 {
public:
static Singleton1* GetInstance() {
if (instance == nullptr) {
instance = new Singleton1();
}
return instance;
}
private:
// 防止外界构造和删除对象
Singleton1() = default;
~Singleton1() = default;
Singleton1(const Singleton1&) = default;
Singleton1& operator=(const Singleton1&) = default;
static Singleton1 *instance;
};
Singleton1* Singleton1::instance = nullptr;
存在内存泄露问题,instance是在堆上的,需要手动释放,但是外界没办法调用delete释放对象
线程安全问题,可能会有多个线程同时分配内存
版本二
C++
class Singleton2 {
public:
static Singleton2* GetInstance() {
if (instance == nullptr) {
instance = new Singleton2();
atexit(Destructor); // 在程序退出的时候释放
}
return instance;
}
private:
// 防止外界构造和删除对象
Singleton2() = default;
~Singleton2() = default;
Singleton2(const Singleton2&) = default;
Singleton2& operator=(const Singleton2&) = default;
static void Destructor() {
if (instance != nullptr) {
delete instance;
instance = nullptr;
}
}
static Singleton2 *instance;
};
Singleton2* Singleton2::instance = nullptr;
解决了内存泄露问题
版本三
C++
class Singleton3 {
public:
static Singleton3* GetInstance() {
if (instance == nullptr) {
lock_guard lock(mutex_);
if (instance == nullptr) {
instance = new Singleton3();
atexit(Destructor);
}
}
return instance;
}
private:
// 防止外界构造和删除对象
Singleton3() = default;
~Singleton3() = default;
Singleton3(const Singleton3&) = default;
Singleton3& operator=(const Singleton3&) = default;
static void Destructor() {
if (instance != nullptr) {
delete instance;
instance = nullptr;
}
}
static Singleton3 *instance;
static mutex mutex_;
};
Singleton3* Singleton3::instance = nullptr;
new的时候的操作分为三步:分配内存、调用构造函数、返回指针
有可能先返回指针当还没有调用构造函数导致对象没有初始化,其他线程获取到没有初始化的对象
版本四
C++
class Singleton4 {
public:
static Singleton4* GetInstance() {
Singleton4* tmp = instance.load(std::memory_order_relaxed);
atomic_thread_fence(std::memory_order_acquire); // 获取内存屏障
if (tmp == nullptr) {
lock_guard lock(mutex_);
tmp = instance.load(memory_order_relaxed);
if (tmp == nullptr) {
tmp = new Singleton4;
atomic_thread_fence(std::memory_order_release); // 释放内存屏障
instance.store(tmp,memory_order_relaxed);
atexit(Destructor);
}
}
return tmp;
}
private:
// 防止外界构造和删除对象
Singleton4() = default;
~Singleton4() = default;
Singleton4(const Singleton4&) = default;
Singleton4& operator=(const Singleton4&) = default;
static void Destructor() {
if (instance != nullptr) {
delete instance;
instance = nullptr;
}
}
static atomic instance;
static mutex mutex_;
};
atomic Singleton4::instance;
mutex Singleton4::mutex_;
版本五
c++11 magic static 特性:如果当变量在初始化的时候,并发同时进⼊声明语句,并发线程将 会阻塞等待初始化结束
C++
class Singleton5 {
public:
static Singleton5& GetInstance() {
static Singleton5 instance;
return instance;
}
private:
Singleton5() = default;
~Singleton5() = default;
Singleton5(const Singleton5&) = default;
Singleton5& operator=(const Singleton5&) = default;
};
版本六
C++
template
class Singleton6 {
public:
static T& GetInstance() {
static T instance;
return instance;
}
protected:
virtual ~Singleton6() = default;
Singleton6() = default;
Singleton6(const Singleton6&) = default;
Singleton6& operator=(const Singleton6&) = default;
};
class DesignPattern : public Singleton6 {
friend class Singleton6;
public:
~DesignPattern() = default;
private:
DesignPattern() = default;
DesignPattern(const DesignPattern&) = default;
DesignPattern& operator=(const DesignPattern&) = default;
};
int main() {
DesignaPattern &d1 = new DesignaPattern::getInstance();
}
THE END
暂无评论内容