你以为你会写单例 其实你不会 完美单例的实现

你以为你会写单例 其实你不会 完美单例的实现,第1张

在大家写单例的时候 懒汉模式 即在定义的时候再分配内存 第一时间想到的便是如下这种模式

class Singleton {
public:
 static Singleton * GetInstance() {
 if (_instance == nullptr) {
 _instance = new Singleton();
 }
 return _instance;
 }
private:
 Singleton(){}//构造
 Singleton(const Singleton &clone){} //拷⻉构造
 Singleton& operator=(const Singleton&) {}
 static Singleton * _instance;
}
Singleton* Singleton::_instance = nullptr;//静态成员需要初始化

公共静态成员函数调用私有构造函数来进行初始化

但是这种方式明显有大问题 首先这个单例什么时候析构呢?其次这个单例是线程安全的嘛?这个单例是可移植的嘛? 不能移植那是不是我每一个单例类都要这么写?

为了解决上面几个问题 完美的单例类诞生了

 

template
class Singleton {
public:
static T& GetInstance() {
 static T instance; // 这⾥要初始化DesignPattern,需要调⽤DesignPattern 构造函数,同时会调⽤⽗类的构造函数。
 return instance;
 }
protected:
 virtual ~Singleton() {}
 Singleton() {} // protected修饰构造函数,才能让别⼈继承
 Singleton(const Singleton&) {}
 Singleton& operator =(const Singleton&) {}
};

读者就要问了 这就自动释放内存了? 是的 静态变量放在全局区 由 *** 作系统释放 这就线程安全了?是的 c++11后 static修饰的变量在初始化时都具有线程安全性 

那为什么就可移植了呢?

看如下的代码

class DesignPattern : public Singleton {
 friend class Singleton; // friend 能让 Singleton 访问到 DesignPattern构造函数
private:
 DesignPattern(){}
 DesignPattern(const DesignPattern&) {}
 DesignPattern& operator=(const DesignPattern&) {}
}

 首先继承的时候指明你的类型 最后把这个类声明为我的友元类 主要是为了让他能访问到我的私有构造函数 这样我在调用GetInstance()方法的时候才能构造我自己 

以后项目里的单例都可以采用这种方式去书写

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1324126.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-12
下一篇2022-06-12

发表评论

登录后才能评论

评论列表(0条)

    保存