单例模式
单例模式是最常用的简单的一种设计模式,根据不同的需求有不同的实现方法。
什么是单例
单例Singleton是设计模式的一种,其特点是单例类只允许一个实例化对象存在,该类自己负责创建自己的对象,同时提供访问其唯一对象的接口。这个实例化对象具有全局变量的特点,在任何地方都可以通过接口获取到那个唯一实例。
优点:1、在内存中只有一个实例,减少了内存开销
2、提高创建速度,因为每次获取都已经存在对象了,尤其对一些需要频繁创建和销毁的实例(如某个网页首页页面缓存)
3、可以全局共享这一个唯一对象。
缺点:因为构造函数的私有化所以不能继承,与单一职责的原则冲突,因为一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景:
1、当整个生产中只需要唯一一个实例时。如设备管理器,系统中可能有多个设备,但是只有一个设备管理器。 2、WEB中的计数器,不用每次刷新都往数据库中加一次,可以先用单例进行缓存。
单例的实现
为了保证线程安全,以前常用的办法就是通过加锁,加锁的开销挺大的。
非局部静态变量在编译时期就已经完成初始化,局部静态变量在程序运行到初始化之处才进行初始化。
所以根据C++11标准中的局部静态变量的特性。提供以下实现方法:
class Singleton{
private:
Singleton(){}
public:
static Singleton& Instance(){
static Singleton instance;
return instance;
}
Singleton(const Singleton& obj)=delete; //禁止拷贝
Singleton& operator = (const Singleton obj)=delete; //禁止赋值
}
另外网上有人的实现返回指针而不是返回引用
这样做并不好,理由主要是无法避免用户使用delete instance导致对象被提前销毁。还是建议大家使用返回引用的方式。
关于C++11中局部静态变量初始化的几点要求:
1、变量在代码第一次执行到变量声明的地方初始化。
2、初始化过程中发生异常的话视为未完成初始化,未完成初始化的话,需要下次有代码执行到相同位置时再次初始化。
3、在当前线程执行到需要初始化变量的地方时,如果有其他线程正在初始化该变量,则阻塞当前线程,直到初始化完成为止。
4、如果初始化过程中发生了对初始化的递归调用,则视为未定义行为。