栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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()方法的时候才能构造我自己 

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947568.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号