以下是阿鲤对设计模式中单例模式的学习分享,希望对大家有用;若有错误请慷慨指出。
1:单例模式的介绍
2:单例模式的实现
2.1:饿汉模式
2.2:懒汉模式
1:单例模式的介绍
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
2:单例模式的实现
2.1:饿汉模式:不管你将来用不用,程序启动时就创建一个唯一的实例对象
#include<iostream>
using namespace std;
//realization one : Starving model
class starv
{
static starv m_instance;
starv()//Constrct function privatization go guarantee single instance
{
cout << "starv( )" << endl;
}
//prevent copy
starv(const starv&);// starv(const starv&) = delete;
starv operator=(const starv&);// starv operator=(const starv&) = delete;
public:
static starv* GetStarc()
{
return &m_instance;
}
};
starv starv::m_instance;//Create a instance before program operation
int main()
{
starv::GetStarc();
system("pause");
return 0;
}
总结:
1. 对象 在第一次使用之前已经存在
2. 构造函数私有化
3. 提供一个static公有接口返回对象
4. 定义一个static自身成员
5. 防拷贝:拷贝构造只声明不实现
优点:简单
缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞争,提高响应速度更好
2.2:懒汉模式; 如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好
#include<iostream>
#include<mutex>
#include<thread>
using namespace std;
class slacker
{
slacker()//Constrct function privatization go guarantee single instance
{
cout << "slacker( )" << endl;
}
//prevent copy
slacker (const slacker&);// starv(const starv&) = delete;
slacker operator=(const slacker&);// starv operator=(const starv&) = delete;
static slacker* instance;//unique instance
static mutex m_mtx;
public:
static slacker* GetObject()
{
if (instance == nullptr)
{
m_mtx.lock();//add lock
if (instance == nullptr)
{
instance = new slacker;
}
m_mtx.unlock();//remove lock
}
return instance;
}
class deconstruction//deconstruction in the way of inner class to prevent repeated deconstructions
{
public:
~deconstruction()
{
if (instance)
{
cout << "deconstruction" << endl;
delete instance;
instance = nullptr;
}
}
};
};
slacker* slacker::instance = nullptr;
mutex slacker::m_mtx;
int main()
{
slacker::GetObject();
slacker::deconstruction();
system("pause");
return 0;
}
总结:
1.对象第一次使用的时候创建
2.构构造函数私有
3. 防拷贝
4. 提供公有的static接口,接口第一次调用时创建对象
5. 定义一个static的指针
6:线程安全:双检查
优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。
缺点:复杂