单件模式比较简单
最常用的写法,子类继承它既可。
template<typename T>
class CSingleton
{
public:
static T& Instance()
{
if (!pInstance_)
{
pInstance_ = new T;
}
return *pInstance_;
}
private:
static T* pInstance_;
protected:
CSingleton(void)
{
}
CSingleton(const CSingleton&);
CSingleton& operator = (const CSingleton&);
};
template<typename T>
T* CSingleton<T>::pInstance_ = NULL;
该写法有个问题,instance_是没有析构了,只有退出应用程序,靠操作系统去回收
改进方案:
将instance申明为static,依赖于c++的语言机制去回收
该方案比较简单,但是也有个小问题,如果单件回收有顺序要求,那就不可控了,static对于C++语言要求的析构顺序是:先申明的后析构。
可以使用一种其它方案:在程序退出main中,可以增加一个函数指针,这个函数指针会在exit中进行调用。我们对每个单件申明一个寿命期的变量,寿命期越长的,越晚析构。
其实就是将它保存到vector中,然后依次从vector中取单件对象进行析构,寿命期越晚的,放到越后面
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LifetimerTracker.h的实现
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <exception>
#include <algorithm>
//using namespace std;
// 带寿命的singletons
class LifetimeTracker
{
public:
LifetimeTracker(unsigned int x)
:longevity_(x)
{
}
virtual ~LifetimeTracker() = 0;
friend bool MyCompare(const LifetimeTracker* pLeft, const LifetimeTracker* pRight);
private:
unsigned int longevity_;
};
inline LifetimeTracker::~LifetimeTracker(){}
bool MyCompare(const LifetimeTracker* pLeft, const LifetimeTracker* pRight);
typedef LifetimeTracker** TrackerArray;
extern TrackerArray pTrackerArray;
extern unsigned int elements;
//////////////////////////////////////////////////////////////////////////
template<typename T>
void Delete(T* pObj)
{
delete pObj;
}
//////////////////////////////////////////////////////////////////////////
template<typename T, typename Destroyer>
class ConcreteLifetimeTracker: public LifetimeTracker
{
public:
ConcreteLifetimeTracker(T* pDynObject, unsigned int longevity, Destroyer destroyer)
: LifetimeTracker(longevity),
pTracked_(pDynObject),
destroyer_(destroyer)
{
}
~ConcreteLifetimeTracker()
{
destroyer_(pTracked_);
}
private:
T* pTracked_;
Destroyer destroyer_;
};
void AtExitfn();
template<typename T, typename Destroyer>
void SetLongevity(T* pDynObject, unsigned int longevity, Destroyer d = Delete<T>)
{
TrackerArray pNewArray = static_cast<TrackerArray>(std::realloc(pTrackerArray, sizeof(ConcreteLifetimeTracker<T, Destroyer>) * (elements + 1)));
if (!pNewArray)
{
throw std::bad_alloc();
}
pTrackerArray = pNewArray;
LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d);
// 用到了一个排序
TrackerArray pos = std::upper_bound(pTrackerArray, pTrackerArray + elements, p, MyCompare);
std::copy_backward(pos, pTrackerArray + elements, pTrackerArray + elements + 1);
*pos = p;
++elements;
_Atexit(AtExitfn);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LifetimerTracker.cpp的实现
#include "StdAfx.h"
#include "LifetimerTracker.h"
TrackerArray pTrackerArray;
unsigned int elements;
void AtExitfn()
{
assert(elements > 0 && pTrackerArray != 0);
LifetimeTracker* pTop = pTrackerArray[elements - 1];
pTrackerArray = static_cast<TrackerArray>(realloc(pTrackerArray, sizeof(TrackerArray) * (--elements)));
delete pTop;
}
bool MyCompare(const LifetimeTracker* pLeft, const LifetimeTracker* pRight)
{
return pLeft->longevity_ < pRight->longevity_;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
简单的测试代码
class CTestSingle
{
public:
static void Create()
{
if (!pInstance_)
{
pInstance_ = new CTestSingle;
SetLongevity<CTestSingle>(pInstance_, 1, Delete<CTestSingle>);
return;
}
CTestSingle* pInstance2 = new CTestSingle;
SetLongevity<CTestSingle>(pInstance2, 2, Delete<CTestSingle>);
}
private:
static CTestSingle* pInstance_;
int i;
};
CTestSingle* CTestSingle::pInstance_ = NULL;
void Bar()
{
}
void Fun()
{
_Atexit(Bar);
}
void CTestSingleton::Test()
{
CTestSingle::Create();
CTestSingle::Create();
//_Atexit(Fun);
//SetLongevity((&(CSingleton::Instance())), 1);
}