1.什么式单列设计模式
单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
2.单例模式的设计套路:
1.即然外部不可以定义对象,也就是说是不可以从外部调到类的构造函数,所以就必须把构造函数私有 化, 但是私有化带来的问题是,在外部一个对象也定义不出来了。 所以必须在类内定义一个公开的接口,返回本类对象的指针。
2.即使用public权限下定义一函数,返回出本类对象的指针。 但是,如果这个函数是一个普通函数的话,那么他还是依赖于类对象的调用才可以,这又与只产生一 个单例相矛盾了。 所以必须,把这个函数升级为静态函数。
3.把这个函数升级为静态函数。 但是,升级为静态函数之后呢?函数就没有this指针,无法调取类中属性,所以也要把类中这个属性升 级为静态属性。
4.把类中的本类的指针,升级为静态属性。
3.单例设计模式的分类
3.1饿汉式
3.1.1饿汉式的优缺点:
优点:对象提前创建好了,使用的时候无需等待,效率高
缺点:对象提前创建,所以会占据一定的内存,内存占用大
以空间换时间
3.1.2饿汉式的代码实现
#include <iostream>
using namespace std;
class Singleton{
static Singleton *singleton;
Singleton()
{
cout<<"这是一个无参构造"<<endl;
}
~Singleton()
{
cout<<"这是析构"<<endl;
}
public:
static Singleton* getinstence()
{
return singleton;
}
void show_info()
{
cout<<this<<endl;
}
//将编译器自动提供的拷贝构造与等号运算符重载移除掉
Singleton(const Singleton& other)=delete ;
void operator=(const Singleton& other)=delete ;
};
Singleton* Singleton::singleton=new Singleton;
int main()
{
Singleton *s1=Singleton::getinstence();
s1->show_info();
Singleton *s2=Singleton::getinstence();
s2->show_info();
Singleton *s3=Singleton::getinstence();
s3->show_info();
return 0;
}
3.1.3结果图
说明定义的三个地址都是一样的,所以实现了单列设计模式。
3.2懒汉式
3.2.1优缺点
优点:
1)使用对象时,对象才创建,所以不会提前占用内存,内存占用小
缺点:
1)首次使用对象时,需要等待对象的创建,而且每次都需要判断对象是否为空,运行效率较低以时间换空间。
2)这个方法其实是存在问题的,试想一下,如果两个线程同时判断singleton为空,那么它们都会去实例化一个Singleton对象,这就变成双例了。所以,我们要解决的是线程安全问题。
所以我们可以加上一个智能锁来解决这个问题lock_guard<mutex> lock(mtx);
3.2.2代码实现
#include <iostream>
#include <mutex>
using namespace std;
mutex mtx;
class Singleton{
static Singleton* singleton;
Singleton()
{
cout<<"这是一个无参构造"<<endl;
}
~Singleton()
{
cout<<"这是析构"<<endl;
}
public:
static Singleton* get_instence()
{
lock_guard<mutex> lock(mtx);
if(singleton==nullptr){
singleton=new Singleton;
}
return singleton;
}
void show_info()
{
cout<<this<<endl;
}
static void destroy()
{
if(singleton!=nullptr){
delete singleton;
}
}
};
Singleton* Singleton::singleton=nullptr;
int main()
{
Singleton *s1=Singleton::get_instence();
s1->show_info();
Singleton *s2=Singleton::get_instence();
s2->show_info();
Singleton *s3=Singleton::get_instence();
s3->show_info();
Singleton::destroy();
return 0;
}