单例模式:用来控制某个类必须在某个应用程序中只能有一个实例存在,它是软件设计的一种常用的设计模式。
控制方式:对单例的控制有两种方式,内部控制和外部控制。
内部控制:在类的内部初始化单例对象的实例,如果是第一次访问,则创建,后面直接拿来用就好了,不需要再创建,目前主要使用内部控制的方式。
外部控制:在每个调用这个单例模型的内部方法中都要判断实例是否存在,如果不存在则创建,存在则直接拿来用。
设计思路:
1、既然类只能有一个实例,我们就需要屏蔽外部通过实例化的形式创建类的实例,所以我们把构造函数声明为私有
2、需要有一个唯一的实例,我们需要为外部提供一个访问这个实例的接口,而这个接口不能依赖于对象,所以我们使用静态成员函数,如GetInstance()。
下面看示例代码:
内部控制方式(头文件):
//inner.h
#include <iostream>
class Singleton
{
private:
static Singleton *m_pObject; //此指针用于特例化
Singleton(); //将构造函数和拷贝构造函数设置为私有,避免对象被显示构造
Singleton(const Singleton& sigObj);
public:
static Singleton* GetInstance();
};
Singleton* Singleton::m_pObject = NULL;
Singleton::Singleton()
{}
Singleton::Singleton(const Singleton& sigObj)
{}
Singleton* Singleton::GetInstance()
{
if(NULL == m_pObject)
m_pObject = new Singleton();
return m_pObject;
}
测试代码:
#include "inner.h" //可以是outer.h
#include <cstdio>
using namespace std;
int main()
{
Singleton *sigObj1 = Singleton::GetInstance();
cout << "sigObj1 addr:" << sigObj1 << endl;
Singleton *sigObj2 = Singleton::GetInstance();
cout << "sigObj2 addr:" << sigObj2 << endl;
char ch = getchar();
}
测试结果如图所示:
外部控制方式:
//outer.h
#include <iostream>
#include <list>
using std::list;
class Singleton
{
private:
static Singleton *m_pObject;
static list<Singleton*> m_Instances;
Singleton();
Singleton(const Singleton& sigObj);
public:
static Singleton* GetInstance();
};
Singleton* Singleton::m_pObject = NULL;
list<Singleton*> Singleton::m_Instances(NULL);
Singleton::Singleton()
{}
Singleton::Singleton(const Singleton& sigObj)
{}
Singleton* Singleton::GetInstance()
{
if(0 == m_Instances.size())
{
m_pObject = new Singleton();
m_Instances.push_back(m_pObject);
}
return m_Instances.front();
}
测试代码将第一行改为:#include "outer.h",其它不变,测试结果如图所示: