定义
单例模也称单子模式,单件模式。通过该可以保证系统中只存在一个实例,并且提供全局访问使其被其他模块共享。打印机,窗口管理器,文件系统 等被共享的资源在系统中只有一个实例很重要。
实现
单例模式只能有一个实例,因此单例模式只能初始化一次 ,初始化后不能通过其他任何途径生成第二个实例。
c++类实例化的方式:
1. 构造函数
2. 拷贝构造函数
3. 复制函数
需要将以上函数声明为私有函数,由类自己管理对象的构建。
单例模式又分为饿汉式单例和懒汉式单例,
- 饿汉模式:在类加载的时候实例化对象
- 懒汉模式:在第一次调用类的时候实例化对象。
在C++ 中一般都使用懒汉式单例,但懒汉式单例可能会有线程安全,异常安全问题。
代码
1、饿汉模式
class Signleton
{
private:
Singleton();
Singleton(const Singleton &);
Singleton& operator = (const Singleton &);
static Singleton *m_Instance;
public:
static Singleton *Getinstance();
}
Singleton *Singleton::m_Instance = new Singleton(); //初始化
static Singleton *Singleton::Getinstance()
{
return m_Instance;
}
2、懒汉模式
class CSingleton
{
private:
CSingleton() //构造函数是私有的
{
}
public:
static CSingleton * GetInstance()
{
static CSingleton *m_pInstance;
if(m_pInstance == NULL) //判断是否第一次调用
m_pInstance = new CSingleton();
return m_pInstance;
}
};
对于拷贝构造和分配操作符如果我们不打算自定义的话,那么最好将它们也置为私有且不实现
考虑线程安全 双层锁定
class Lock
{
private:
CCriticalSection m_cs;
public:
Lock(CCriticalSection cs) : m_cs(cs)
{
m_cs.Lock();
}
~Lock()
{
m_cs.Unlock();
}
};
class CSingleton
{
private:
CSingleton();
CSingleton(const CSingleton &);
CSingleton& operator = (const CSingleton &);
public:
static CSingleton *Getinstance();
static CSingleton *m_Instance;
static CCriticalSection cs;
};
CSingleton* CSingleton::m_Instance = 0;
CSingleton* CSingleton::Getinstance()
{
if(m_Instance == NULL)
{ //double check
Lock lock(cs); //用lock实现线程安全,用资源管理类,实现异常安全
//使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。
if(m_Instance == NULL)
{
m_Instance = new Singleton();
}
}
return m_Instance;
}
参考
https://www.cnblogs.com/qianqiannian/p/6541884.html
https://www.cnblogs.com/ZhYQ-Note/articles/6089444.html