5、单例模式(Singleton)
使用场景:
保证一个类仅有一个实例,并提供一个访问它的全局访问点,一个全局使用的类频繁地创建与销毁
关键代码:
构造函数是私有的
优点:
a) 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
b) 避免对资源的多重占用
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化
模式结构:
a) 单例类:包含一个实例且能自行创建这个实例的类。
b) 访问类:使用单例的类。
第 1 种:懒汉式单例
#include <iostream>
#include <vector>
using namespace std;
class LazySingleton {
private:
static LazySingleton* instance_ptr;
LazySingleton(){
std::cout << "constructor called!" << std::endl;
}
public:
static LazySingleton* get_instance(){
if (instance_ptr == nullptr){
instance_ptr = new LazySingleton;
}
return instance_ptr;
}
};
LazySingleton* LazySingleton::instance_ptr = nullptr;
int main() {
LazySingleton* instance = LazySingleton::get_instance();
LazySingleton* instance_2 = LazySingleton::get_instance();
return 0;
}
运行结果:
第 2 种:饿汉式单例
#include <iostream>
using namespace std;
class HungrySingleton
{
public:
static HungrySingleton* GetInstance()
{
return &m_instance;
}
private:
HungrySingleton(){
cout << "constructor called!" << endl;
};
HungrySingleton(HungrySingleton const&);
HungrySingleton& operator=(HungrySingleton const&);
static HungrySingleton m_instance;
};
HungrySingleton HungrySingleton::m_instance; // 在程序入口之前就完成单例对象的初始化
int main()
{
HungrySingleton* instance = HungrySingleton::GetInstance();
HungrySingleton* instance_2 = HungrySingleton::GetInstance();
return 0;
}
运行结果: