什么是设计模式?
设计模式代表了最佳的实践。是软件开发人员在软件开发过程中面临的一般问题的解决方法。这些解决方案是众多软件开发人员经过相当长一段时间的试验和经验错误总结出来的。
所以,设计模式是一套被反复使用的,多数人知晓、经过分类编目的、代码设计经验的总结。
什么是单例模式?
- 单例:一个类只能实例化出一个实例
- 模式:软件开发过程中,软件开发人员总结出的一套解决一般问题的方案
如何实现一个单例模式?
- 懒汉模式
class singleton
{
public:
//定义一个接口函数,用来创建实例对象
singleton* GetInstance()
{
if (_sInstance == NULL)
{
_sInstance = new singleton;
}
return _sIntance;
}
private:
//定义构造函数为私有
singleton(int data = 0)
:_data(data)
{}
//防拷贝
singleton(singleton& s);
singleton* operator=(singleton& s);
//定义一个指向实例的指针,如果为空,就可以创建实例,否则就不能创建
static singleton* _sInstance;
int _data;
};
singleton::_sInstance = NULL;
上面的代码可以实现一个最简单的单例模式。可是线程不安全,这个问题该如何解决呢?
给临界区代码加锁就好了。
#include <mutex>
class singleton
{
public:
//定义一个接口函数,用来创建实例对象
singleton* GetInstance()
{
_mtx.lock(); //保证线程安全
if (_sInstance == NULL)
{
_sInstance = new singleton;
}
_mtx.unlock();
return _sIntance;
}
private:
//定义构造函数为私有
singleton(int data = 0)
:_data(data)
{}
//防拷贝
singleton(singleton& s);
singleton* operator=(singleton& s);
//定义一个指向实例的指针,如果为空,就可以创建实例,否则就不能创建
static singleton* _sInstance;
int _data;
mutex _mtx;
};
singleton::_sInstance = NULL;
singleton::_mtx;
可是这样又有了新的问题,如果在锁的操作中抛了异常,就有可能会导致死锁的情况发生;于是想办法将它向智能指针一样管理起来,让系统自动的申请锁和释放锁:使用基于RAII思想实现的lock_goard(C++11)。
最后,还有一个问题,在实际中,我们只要在第一次的时候加锁就好了,否则就会影响效率:
singleton* GetInstance()
{
//双重检查,保证效率
if (_sInstance == NULL)
{
_mtx.lock(); //保证线程安全
if (_sInstance == NULL)
{
_sInstance = new singleton();
}
_mtx.unlock();
}
return _sIntance;
}
- 饿汉模式
class singleton
{
public:
//定义一个接口函数,用来创建实例对象
singleton* GetInstance()
{
assert(_sInstance);
return _sIntance;
}
private:
//定义构造函数为私有
singleton(int data = 0)
:_data(data)
{}
//防拷贝
singleton(singleton& s);
singleton* operator=(singleton& s);
//定义一个指向实例的指针
static singleton* _sInstance;
int _data;
};
singleton::_sInstance = new singleton();