2008年7月18日 星期五

隱身在幕後的Singleton

今天看到一個很好玩的架構,我稱之為「隱身在幕後的Singleton」。

我們有一個Symbol類別,物件放在Symbol Table中,這個Symbol Table是一個Singleton。


class CSymbol
{
public:
  // constructor, destructor
  CSymbol( char const* pStr );
protected:
  // Initializes the symbol table
  static void InitializeTable();
  // returns the current symbol table
  static CSymbolTable* GetTable();
  // The standard global symbol table
  static CSymbolTable* s_pSymbolTable;
  friend class CCleanupSymbolTable;
};


class CCleanupSymbolTable
{
public:
  ~CCleanupSymbolTable();
};


class CSymbolTable
{
public:
  CSymbolTable();
  ~CSymbolTable();
};

SymbolTable 是放在 Symbol 類別裡的一個靜態成員資料,所以,所有的 Symbol 都共用相同一個。
一開始這個 Table 是不存在的,在 Symbol 的建構子裡面,會呼叫 GetTable() 函式, 這個函式會new 一個 Table 出來,如果沒有的話。
也就是,第一次建立 Symbol 物件時,就會自動地建立 Symbol Table 。

CleanupSymbolTable 物件只有定義一個解構子,它的 code 是這樣:

CCleanupSymbolTable::~CCleanupSymbolTable()
{
  if (CSymbol::s_pSymbolTable) delete CSymbol::s_pSymbolTable;
  CSymbol::s_pSymbolTable = 0;
}


所以這個物件的用處沒別的,就是在解構子裡面 delete 掉 Symbol Table Singleton。
然後我們再宣告一個靜態物件變數。

static CCleanupSymbolTable g_CleanupSymbolTable;

這樣,當程式結束的時候,程式會清除靜態變數 g_CleanupSymbolTable,而這個變數被清除時,會 delete 掉 Symbol Table。 所以這個 Symbol Table 就像是隱形了一樣,不需要外部呼叫new / delete,用到它的時候,自然會 new 出來,程式結束會自動 delete 掉。

完全的全自動操作。

沒有留言: