定义:保证1个类仅有1个实例,并提供一个访问他的全局访问点
如果希望在系统中某个类的对象只能存在1个,那么就使用单例模式,比如配置类
主要解决了:全局使用的类频繁的创建与销毁
优点:避免了对资源的多重占用。在内存里只有1个实例,减少内存的开销,尤其是频繁的创建和销毁实例
---------------------------------------------------------------------------------------------------------------------------------
步骤:
1、将构造函数设为私有,拷贝构造函数设置为私有(或者delete掉),赋值函数设置为私有(或者delete掉)
2、提供1个静态的访问唯一实例的接口
---------------------------------------------------------------------------------------------------------------------------------实现有2种:
- 饿汉
直接在程序运行之前就初始化好了这个实例
class SingleTon2 {
public://3、设置一个静态的访问实例接口 static SingleTon2* getInstance(){return data;}
private://1、将构造函数和拷贝构造私有化SingleTon2() = default;SingleTon2(const SingleTon2& other) = default;SingleTon2& operator=(const SingleTon2& othe) = delete;
private://2、指向本类的静态指针static SingleTon2* data;};
//4、程序运行之前就对这个实例进行了初始化
SingleTon2* SingleTon2::data = new SingleTon2;
- 懒汉
需要访问这个实例时才初始化这个实例
但是存在多线程访问仍然可能导致有多个实例的问题
class SingleTon {
public://3、设置一个静态的访问实例接口 static SingleTon* getInstance(){///4、程序运行之后调用该接口访问这个实例时才对这个实例进行初始化if (data == nullptr){data = new SingleTon;}return data;}
private://1、将构造函数和拷贝构造、赋值函数私有化SingleTon() = default;SingleTon(const SingleTon& other) = default;//或者deleteSingleTon& operator=(const SingleTon& othe) = delete;private://2、指向本类的静态指针static SingleTon* data;};
SingleTon* SingleTon::data = nullptr;
使用局部静态变量解决线程安全问题
class SingleTon3 {
public://2、设置一个静态的访问实例接口 static SingleTon3* getInstance(){//3、静态局部变量只会初始化一次 且生命周期整个程序运行期间static SingleTon3 data;return &data;}
private://1、将构造函数和拷贝构造、赋值函数私有化SingleTon3() = default;SingleTon3(const SingleTon3& other) = default;//或者deleteSingleTon3& operator=(const SingleTon3& othe) = delete;
};
还可以使用std::call_once解决多线程访问的问题
class SingleTon4 {
public://3、设置一个静态的访问实例接口 static SingleTon4* getInstance(){///4、程序运行之后调用该接口访问这个实例时才对这个实例进行初始化if (data == nullptr){//声明这个once_flag 搭配call_once保证只调用1次初始化操作static once_flag once;call_once(once, [&]() {data = new SingleTon4; });}return data;}
private://1、将构造函数和拷贝构造、赋值函数私有化SingleTon4() = default;SingleTon4(const SingleTon4& other) = default;//或者deleteSingleTon4& operator=(const SingleTon4& othe) = delete;private://2、指向本类的静态指针static SingleTon4* data;};
SingleTon4* SingleTon4::data = nullptr;