第六章(单件模式)

单件模式比较简单

最常用的写法,子类继承它既可。

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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值