单件模式
根据GOF的《设计模式:可复用面向对象软件的基础》中是这样描述的:保证一个类只有一个实例,并提供一个访问它的全局访问点。
适用性
在下面的情况下可以使用Singleton模式
1,当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2,当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需要更改代码就能使用一个扩展的实例时。
结构:
代码实现:
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton *getInstance()
{
if(nullptr == m_Instance)
{
m_Instance = new Singleton();
}
return m_Instance;
}
static void DestoryInstance()
{
if(nullptr != m_Instance)
{
delete m_Instance;
m_Instance = nullptr;
}
cout << "DestoryInstance()============" << endl;
}
int GetData()
{
return m_nData;
}
private:
Singleton()
{
m_nData = 25;
}
static Singleton *m_Instance;
int m_nData;
};
Singleton *Singleton::m_Instance = nullptr;
int main()
{
Singleton *singletion = Singleton::getInstance();
cout << "singletion->GetData()============" << singletion->GetData() << endl;
Singleton::DestoryInstance();
cout << "Hello World!" << endl;
return 0;
}
上面这种是最普通的实现方式,虽然单件模式就一个类,看起很简单,但在应该的时候还需要考滤一些实际的问题,比如说如果是在多线程环境下使用,这个就不合适了。下面看第二种实出方式
//Qt环境下运行
#include <QCoreApplication>
#include <iostream>
#include <QMutex>
using namespace std;
static QMutex mutex;
class Singleton
{
public:
static Singleton *getInstance()
{
if(nullptr == m_Instance)
{
cout << "mutex.lock()=================" << endl;
mutex.lock(); //lock操作, QMutex
if(nullptr == m_Instance)
{
m_Instance = new Singleton();
}
mutex.unlock(); //释放操作 QMutex
cout << "mutex.unlock()===============" << endl;
}
return m_Instance;
}
static void DestoryInstance()
{
if(nullptr != m_Instance)
{
delete m_Instance;
m_Instance = nullptr;
}
cout << "DestoryInstance()============" << endl;
}
int GetData()
{
return m_nData;
}
private:
Singleton()
{
m_nData = 25;
}
static Singleton *m_Instance;
int m_nData;
};
Singleton *Singleton::m_Instance = nullptr;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Singleton *singletion = Singleton::getInstance();
cout << "singletion->GetData()============" << singletion->GetData() << endl;
Singleton::DestoryInstance();
cout << "Hello World!" << endl;
return a.exec();
}
参与者
Singleton
——定义一个Instance操作,允许客户访问他的唯一实例。
——可能负责创建它自己的唯一实例
总结
Singleton模式有许多优点:
1)对唯一实例的受控访问 因为Singleton类封装它的唯一实例,所以它可以严可的控制客户怎么以及何时访问它。
2)缩小名空间 Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。
3)允许对操作和表示的精化 Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。你可以用你所需要的类的实例在运行时刻配置应用。
4)允许可变数目的实例 这个模式使得你易于改变你的想法,并允许Singleton类的多个实例。此外,你可以用相同的方法来控件应用所使用的实例的数目。只有允许访问Singleton实例的操作需要改变。
5)比类操作更灵活 另一种封装单件功能的方式是使用操作(即C++中的静态成员函数或者是Smalltalk中的类方法)。但这两种语言技术都难以改变设计以允许一个类有多个实例。此外,C++中的静态成员函数不是虚函数,因此子类不能多态的重定义他们。
参考: