文章目录
前言
单例模式是23种设计模式中最常用的一种模式。一个类只能创建一个对象,让类自身负责保存它的唯一实例,并提供一个访问它的全局访问接口,这就是单例模式。
Singleton类 | 单例模式 |
---|---|
-instance | 私有 |
-Singeton() | 私有构造函数 |
+GetInstance() | 访问接口,静态方法 |
一、单例模式的应用场景
1、windows桌面上,已打开了一个回收站,试图再次打开一个新的回收站时,Windows系统并不会为你弹出一个新的回收站窗口。,也就是说在整个系统运行的过程中,系统只维护一个回收站的实例。这就是一个典型的单例模式运用。
2、网站的计数器,一般采用单例模式实现,如果存在多个计数器,每一个用户的访问都刷新计数器的值,计数值是难以同步的。但是如果采用单例模式本来就同步,而且还可以避免线程安全问题。
3、服务器的配置信息,存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理,如HttpApplication。
适用场景如下:
- 需要生成唯一序列的环境
- 需要频繁实例化然后销毁的对象。
- 创建对象时耗资源过多,但又常用的对象。
- 方便资源相互通信的环境
二、单例模式的实现
从具体实现的角度来说:
- 该类提供了一个静态的公有函数用于创建或者获取它本身的静态私有对象;
- 类定义中含有一个该类的静态私有对象;
- 单例模式的类只提供私有的构造函数,防止多个实例创建。
1.饿汉式(Eager Singleton)
饿了肯定要饥不择食。所以在单例类定义的时候,即一开始就进行实例化。(本身就是线程安全的,如下例子)
class Singleton{
public:
static Singleton* GetInstance(){
return &instance; // 返回指针
}
private:
static Singleton instance;
Singleton(){
};// 构造函数私有,防止外界利用new创建此实例,
Singleton(const Singleton&) =delete; //防止拷贝
Singleton& operator=(const Singleton&) =delete; //防止赋值
};
Singleton Singleton::instance; //在程序入口之前就完成单例对象的初始化
由于在main函数之前初始化,所以没有线程安全的问题。但是潜在问题是no-local static对象(函数外的static对象)在不同编译单元中的初始化顺序是未定义的。也即static Singleton instance
和static Singleton& getInstance()
二者的初始化顺序不确定,如果在初始化完成之前调用 getInstance() 方法会返回一个未定义的实例。
2.懒汉模式-单线程(Lazy Singleton)
即懒汉版(Lazy Singleton):单例实例在第一次被使用时才进行初始化,这叫做延迟初始化。
2.1 简易版
class