单例模式:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全
局访问点,该实例被所有程序模块共享
单例模式的实现分为饿汉模式和懒汉模式
程序启动时就创建一个唯一的实例对象,去加载所有的资源(预加载)
在静态区创建对象
class Singleton {
public:
static Singleton& GetInstance(){
return _inst;
}
private:
//构造函数私有化
Singleton(){}
//防拷贝
Singleton(const Singleton&) = delete;
Singleton operator=(Singleton) = delete;
//创建静态对象,保证只有一个对象
static Singleton _inst;
};
Singleton Singleton::_inst;
在堆上创建对象
class Singleton {
public:
static Singleton* GetInstance() {
return _inst;
}
private:
//构造函数私有化
Singleton() {}
//防拷贝
Singleton(const Singleton&) = delete;
Singleton operator=(Singleton) = delete;
//创建静态对象,保证只有一个对象
static Singleton* _inst;
};
Singleton* Singleton::_inst = new Singleton;
饿汉模式是在类加载阶段就已经完成了对象的初始化,所以饿汉模式不存在线程安全问题
但是正因为如此,如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好
堆区版本的懒汉模式
class Singleton {
public:
static Singleton* GetInstance() {
//双检查,在没有对象创建的时候才去获取锁,创建对象
if (_inst == nullptr) {
_mtx.lock();
if (_inst == nullptr) {
_inst = new Singleton;
}
_mtx.unlock();
}
return _inst;
}
static void DelInstance() {
_mtx.lock();
if (_inst) {
delete _inst;
_inst = nullptr;
}
_mtx.unlock();
}
// 实现一个内嵌垃圾回收类
class CGarbo {
public:
~CGarbo() {
if (_inst) {
delete _inst;
_inst = nullptr;
}
}
};
private:
//构造函数私有化
Singleton() {}
//防拷贝
Singleton(const Singleton&) = delete;
Singleton operator=(Singleton) = delete;
//创建静态对象,保证只有一个对象
static Singleton* _inst;
static mutex _mtx;
static CGarbo _cg;
};
Singleton* Singleton::_inst = nullptr;
mutex Singleton::_mtx;
Singleton::CGarbo Singleton::_cg;
静态区版本的懒汉模式
class Singleton {
public:
static Singleton& GetInstance() {
static Singleton inst;
return inst;
}
private:
//构造函数私有化
Singleton() {}
//防拷贝
Singleton(const Singleton&) = delete;
Singleton operator=(Singleton) = delete;
};
这种方法不必考虑线程安全问题,编写十分简单
这种方式有一些缺陷
饿汉模式
优点
缺点
懒汉模式
优点
缺点