在大家写单例的时候 懒汉模式 即在定义的时候再分配内存 第一时间想到的便是如下这种模式
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<typename T>
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<DesignPattern> {
friend class Singleton<DesignPattern>; // friend 能让 Singleton<T> 访问到 DesignPattern构造函数
private:
DesignPattern(){}
DesignPattern(const DesignPattern&) {}
DesignPattern& operator=(const DesignPattern&) {}
}
首先继承的时候指明你的类型 最后把这个类声明为我的友元类 主要是为了让他能访问到我的私有构造函数 这样我在调用GetInstance()方法的时候才能构造我自己
以后项目里的单例都可以采用这种方式去书写