关于单例模式,在接触面向对象的设计模式的小伙伴应该不陌生。今天我们来分别介绍一下单例模式中的饿汉模式和懒汉模式。
先来看一下实现单例模式的原理:
1、禁止在类外创建类对象,把构造函数、拷贝构造私有化
2、确保类对象只有一份,在类中定一个静态成员指针变量或类对象
3、提供一个获取静态类对象、指针的接口,设计静态成员函数用于获取静态类对象、指针
现在来看一下饿汉模式的单例:程序运行时就实例化出类对象,不管后期是否用到都会创建出来
cpp
//饿汉模式
#include <iostream>
using namespace std;
class Single
{
static Single obj;
Single(void)
{}
Single(Single &that)
{}
public:
static Single &get_single(void)
{
return obj;
}
};
Single Single::obj;
int main()
{
Single &s1 = Single::get_single();
Single &s2 = Single::get_single();
//Single *s3 = new Single(); // 注意:不能通过new创建单例对象,否则会出现多个实例
cout<<&s1<<" "<<&s2<<endl;
return 0;
}
优点:不可能被多个线程同时运行时创建多份 (线程安全)
缺点:如果后期使用不到单例对象,浪费了资源
再来看懒汉模式的单例: 直到真正使用时才创建单例类对象
cpp
//懒汉模式
#include <iostream>
#include <pthread.h>
using namespace std;
class Single
{
static Single *obj;
Single(void)
{
cout<<"构造"<<endl;
}
Single(Single &that) {}
public:
static Single &get_single(void)
{
if(NULL==obj)
{
obj=new Single;
}
return *obj;
}
};
Single *Single::obj;
void *run(void *arg)
{
Single &s=Single::get_single();
return NULL;
}
int main()
{
Single &s1=Single::get_single();
Single &s2=Single::get_single();
cout<<&s1<<" "<<&s2<<endl;
for(int i=0;i<100;i++)
{
pthread_t tid;
pthread_create(&tid,NULL,run,NULL);
}
return 0;
}
优点:什么时候用什么时候创建,如果用不到就不会创建,节约了资源
缺点:可能多个线程同时创建,有可能会创建多份单例对象(线程不安全)(线程竞争问题)
上面是分别用饿汉模式和懒汉模式实现的单例,饿汉模式和懒汉模式各有其优缺点。
关于单例模式的应用场景
1、任务管理器\日志管理器
2、网站访问计数器
3、线程池、内存池
4、服务器的连接管理器
over