定义
单体(Singleton)模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。
理解
1. Singleton模式用来取代全局静态变量。C++通过静态成员变量来实现类实例全局唯一性。
2. instance()方法是单体提供的唯一调用入口。
要点
1. 为了防止外界调用产生多个实例,将构造方法、析构方法、拷贝构造方法、赋值重载方法都作为private/protected。
2. instance()方法产生对象方式有两种:使用局部static对象,生命期在首次进入局部生命期产生,在程序结束时销毁;通过new产生新对象,在析构方法中delete对象。
3. 获取单体实例调用方式:Singleton::instance()获取对象指针。
4. 解决多线程资源竞争条件。使用著名的“双检测锁定”办法来解决,即在锁定前和锁定后都检测对象是否产生,这样既能保证加锁效率又能保证单件实例的唯一性。
应用
1. 代码部分使用类模版单体(CSingleton<T>),可产生不同种类的单件类。
2. 一个类要成为单体类,把单体类作为自己的友元来实现。因为CSingleton的构造和析构都是private/protected。另外也有通过继承单体来实现。
template <classT>
class CSingleton
{
public:
static inline T* Instance();
private:
CSingleton(void){}
~CSingleton(void){}
CSingleton(const CSingleton&){}
CSingleton & operator= (constCSingleton &){}
static auto_ptr<T> _instance;
static CQuickLock _rs;
};
template <classT>
auto_ptr<T>CSingleton<T>::_instance;
template <classT>
CQuickLockCSingleton<T>::_rs;
/**************************************************************************
Function: Instance
Description: getsingleton object
Input:
Output: -
Return: - T*
Others: -
**************************************************************************/
template <classT>
inline T*CSingleton<T>::Instance()
{
if( 0 == _instance.get() )
{
//CScopedLock lock(_rs);
if( 0== _instance.get())
{
_instance.reset ( new T);
}
}
return _instance.get();
}
/Singleton应用实例
class CMyLog
{
friend classauto_ptr<CMyLog>; //作为友元可以访问CMyLog的私有成员
friend classCSingleton<CMyLog>; //作为友元可以访问CMyLog的私有成员
public:
void Log(char* pszStr)
{
cout << "Log msg: "<< pszStr << endl;
}
private:
CMyLog(){}; //不允许直接实例化
virtual ~CMyLog(void);
};
int main()
{
CMyLog* pLog =CSingleton<CMyLog>::Instance();
pLog->Log("hello word");
system("pause");
return 0;
}
备注:
1、智能指针auto_ptr是一个模板类,适合于任何类型。主要是为了解决“被异常抛出时发生资源泄漏”的问题。即使在函数执行过程时发生异常退出,也会因为异常能保证局部对象被析构从而保证资源被释放。
我们定义一个智能指针,就是定义了一个auto_ptr类的对象,如:auto_ptr<string> p (new string);
这句话就定义了一个auto_ptr类的对象p,尖括号里面的string用来初始化它的模板成员_Ty的类型。那么这里面,只要auto_ptr对象存在,它指向的字符串就存在,同理,如果auto_ptr对象不存在,auto_ptr类中的析构函数自动销毁它所指向的字符串,也就避免了内存泄露。
2、friend classauto_ptr<CMyLog>;
说明auto_ptr类是CMyLog类的友元类,在auto_ptr中可以访问CMyLog类的私有成员。为了在智能指针析构的时候可以调用CMyLog类的私有析构函数
3、friend classCSingleton< CMyLog>;
说明CSingleton单体类是CMyLog类的友元类,在CSingleton中可以访问CMyLog类的私有成员。为了在单体类中创建CMyLog时候可以调用CMyLog类的私有构造函数
4、staticauto_ptr<T> _instance;
CSingleton< CMyLog>; ,类型参数T为CMyLog,CSingleton类中staticauto_ptr< CMyLog> _instance;
_instance.reset ( new CMyLog ) ;
智能指针指向CMyLog的对象,智能指针释放时会调用CMyLog的析构函数。(正常情况下这个静态的智能指针在程序退出时释放)