1.设计模式的概念
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
2.单例模式
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
3.设计一个类为单例类的关键点
(1)单例类保证全局只有唯一一个实例对象;
(2)单例类提供获取这个借口的唯一实例.
4.模拟实现线程安全的单例模式
(1)模拟实现懒汉模式的单例模式(类加载时不初始化,要用的时候才初始化,延时加载,实现较复杂)
class Lock
{
public:
explicit Lock(mutex& mtx) //加锁,加explicit防止被隐式类型转换
:_mtx(mtx)
{
_mtx.lock();
}
~Lock() //解锁
{
_mtx.unlock();
}
private:
mutex& _mtx;
Lock(Lock&);
Lock& operator=(Lock&);
};
class LazySingleton
{
public:
static LazySingleton* GetInstance();
protected:
LazySingleton() //保证全局只有唯一一个实例,将构造函数声明为私有
:_a(0)
{}
LazySingleton(LazySingleton&); //为了更加保险,将拷贝构造和赋值运算符的重载也设置为防拷贝
LazySingleton& operator=(LazySingleton&);
private:
int _a;
static LazySingleton* _inst; //静态成员变量需在类内声明,类外初始化,作为唯一实例的指针
};
LazySingleton* LazySingleton::_inst = NULL;
LazySingleton* LazySingleton::GetInstance()
{
//为了实现线程安全,需要在这个地方加锁,采用RAII的方式封装锁
mutex mtx;
Lock a(mtx);
if (_inst == NULL)
_inst = new LazySingleton;
return _inst;
}
(2)饿汉模式(一上来就初始化,类加载较慢,占用系统资源,但是使用时获取对象的速度快,实现简单)
class EagerSingleton
{
public:
static EagerSingleton* getInstence()
{
return _inst;
}
private:
EagerSingleton()
:_a(0)
{}
static EagerSingleton* _inst;
int _a;
};
EagerSingleton* EagerSingleton::_inst = new EagerSingleton();
5.单例模式的适应场景
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如Windows的Task Manager(任务管理器),应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。