何为单例
一个类,在外部只能生成一个实例,最大限度的减小资源占用
设计思路
问题
绕过常规的构造函数,提供一种机制来保证一个类只有一个实例
解决
- 外部不可以定义对象,即:不能从外部调用到类的构造函数,所以必须把构造函数私有化
- 在public权限下定义成员函数,返回本类对象的指针,但是如果是一个普通函数的话,那么还是要依赖类对象的调用才可以,与只产生一个单例相矛盾,所以必须将此函数升级为静态函数
- 把成员函数升级为静态函数后,函数没有this指针,无法调取类中的属性,所以必须要把类中的这个属性升级为静态属性
- 把类中的本类的指针,升级为静态属性。并在类外完成初始化,初始化则是给定的一个唯一的实例
以下为饿汉式:
- 优点:线程安全
- 缺点:一直占用一块堆上的资源
#include <iostream>
using namespace std;
class Singleton
{
private:
//1.把类中的构造设置成为私有,实现单例
Singleton()
{
cout << "singleton structure" << endl;
}
static Singleton* my_instance;
public:
//2.提供一个公有接口函数返回本对象的指针
//3.公有接口不想依赖类对象的调用,把该接口升级为static静态成员函数
static Singleton* get_my_instance()
{
//4.在类私有属性中定义一个静态的私有成员对象类型的属性指针,并把该指针在公有接口中返回出去
return my_instance;
}
};
//5.在类外完成对类中静态属性指针的初始化
Singleton* Singleton::get_my_instance=new Singleton();
int main()
{
Singleton* s1=Singleton::get_my_instance();
Singleton* s2=Singleton::get_my_instance();
Singleton* s3=Singleton::get_my_instance();
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
return 0;
}
以下为懒汉式:
- 优点:不用不占用资源
- 缺点:
- 生成死递归,所以懒汉不提供析构,只能自己创建
- 不在使用全部申请的空间,线程不安全,所以要加智能锁
#include <iostream>
#include <mutex>
using namespace std;
//设置全局锁
mutex mtx;
class Singleton
{
private:
Singleton()
{
cout << "singleton structure" << endl;
}
//1.把类中的构造设置成私有,实现单例
static Singleton* my_instance;
public:
//2.提供一个公有接口函数返回本对象的指针
//3.公有接口不想依赖类对象的调用,则把该接口升级成为static静态成员函数
static Singleton* get_my_instance()
{
//c++11智能锁类型(可被析构)
lock_guard<mutex> lock(mtx);//c++11线程安全的懒汉单例
//4.在类私有属性中定义一个静态的私有成员对象类型的属性指针,并把该指针在公有接口中返回出去
if(nullptr==my_instance)
{
my_instance=new Singleton();
}
return my_instance;
}
//自定义的懒汉析构方法
void destory()
{
if(nullptr!=my_instance)
{
cout << "singleton destory" << endl;
delete my_instance;
my_instance=nullptr;
}
}
// ~Singleton()
// {
// cout << "singleton destruct" << endl;
// delete my_instance;//析构会出现死递归现象,所以懒汉模型没有析构
// }
};
//5.在类外完成对类中静态属性指针的初始化
Singleton* Singleton::get_my_instance=nullptr;
int main()
{
Singleton* s1=Singleton::get_my_instance();
Singleton* s2=Singleton::get_my_instance();
Singleton* s3=Singleton::get_my_instance();
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
s2->destory();
s3->destory();
return 0;
}
注意:类中的静态属性当其初始化时,可以调用类中的私有属性和方法