2010年8月17日 星期二

Singleton 的 C++ 範例

Singleton 翻譯作 "獨身" 對於取代全域物件,Singleton 是個安全又方便的方法。

舉例來說,若有一個系統流程是必須 "登入會員" 那麼登入成功後,會員資訊看起來是會影響到不少其他的流程,若是寫網頁,我們常常利用 Session 來存放登入者的會員資料,並利用 Session 的特性,在瀏灠器中隨處都可以獲得與修改這些資料,在桌面程式中,全域變數也可以達成這種效果,但 OO 愛好者並不喜歡宣告全域變數,Singleton 這時就派上用場了,即符合 OO 概念又可以取代 global variable

Global Variable的範例


class CUserData
{
  private:
  TCHAR *m_strUserName;
  LONGLONG m_llUserID;
  LONGLONG m_llUserExpireTime;
  public:
  BOOL SetUserName(const TCHAR *pstrName);
  TCHAR GetUserName();
  BOOL SetUserID(const LONGLONG llID);
  LONGLONG GetUserID();
  BOOL SetUserExpireTime(const LONGLONG llTime);
  BOOL SetUserExpireTime(const CTime &ctExpire);
  LONGLONG GetUserExpireTime();
};



CUserData g_UserData;

int main()
{
  // 完成登入
  g_UserData.SetUserID(llMemberID);
  return TRUE;
}

void foo()
{
  CString strMsg;
  strMsg.Format(_T("%s 您好,觀迎使用本系統"), g_UserData.GetUserName());
}


以下是使用 Singleton 的範例


class CUserData
{
private:
  TCHAR *m_strUserName;
  LONGLONG m_llUserID;
  LONGLONG m_llUserExpireTime;
public:
  // 加入一個 member function 用來取得獨身
  static CUserData* GetInstance();
  // 這個 function 必須是 static function
  // 如此才可以不宣告物件實體取用這個函式
 
  BOOL SetUserName(const TCHAR *pstrName);
  TCHAR GetUserName();
  BOOL SetUserID(const LONGLONG llID);
  LONGLONG GetUserID();
  BOOL SetUserExpireTime(const LONGLONG llTime);
  BOOL SetUserExpireTime(const CTime &ctExpire);
  LONGLONG GetUserExpireTime();
};



CUserData* CUserData::GetInstance()
{
  static CUserData *pInst;
  return pInst;
}


往後在 main 或任一 function 中要使用這個唯一實體,即可如此呼叫


(CUserData::GetInstance())->member


例如


void foo()
{
  CString strMsg;
  CString strMemberName = (CUserData::GetInstance())->GetUserName();
  strMsg.Format(_T("%s 您好,觀迎使用本系統"), strMemberName);
}



1 則留言: