程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 關於構造單實例類的一個問題

關於構造單實例類的一個問題

編輯:關於VC++

最近一個朋友問我創建單實例的一個問題,他寫了一個C++單實例類CSingleton,其構造函數也是private類型。這個類有一個靜態函數:GetInstance,它返回單實例類對象的引用,只要用這個函數聲明實例便可以限制對象的復制:// 這一句編譯器通不過
CSingleton temp = CSingleton::GetInstance();

但是編譯器始終在上面這行代碼處受阻。這到底是為什麼呢?

其實,這個問題只要弄清楚編譯器處理單實例類的一些細節,問題便會迎刃而解。當編譯器碰到上面的這條語句時,它會去尋找類的拷貝構造函數,所謂的拷貝構造函數,就是一個署名為CSingleton(const CSingleton&)的構造函數。如果你沒有提供這個拷貝構造函數,那麼C++編譯器會為你提供一個默認的拷貝構造函數。這個默認的拷貝構造函數做的事情很簡單,只是將字節從一個對象靠到另一個對象。如果你想這個拷貝構造函數它干點別的什麼事情,你必須實現自己的拷貝構造函數。為了限制對象的復制,還必須使這個拷貝構造函數為private類型:

class CSingleton {
private:
 // 私有類型的拷貝構造函數
 CSingleton(const CSingleton& obj)
 { ASSERT(FALSE); } // should never happen
};

此外,你還必須實現默認的構造函數,也就是不帶參數的構造函數,如果沒有默認的構造函數,你將不能創建對象實例。默認的構造函數可以是private類型,也可以是protected類型,這要看你是不是想要從CSingleton派生其它的類。總而言之,要想正確創建單實例類,下面的這些原則或訣竅對你是有幫助的:

創建默認構造函數、拷貝構造函數和賦值操作符,並且它們的類型都為私有類型。

創建一個靜態函數GetInstance,用它來返回唯一的對象實例

下面是一個具體的例子代碼:

// 如果你編譯這個程序,會產生錯誤。參見main函數的注釋
//
class CSingleton {
public:
  static CSingleton& GetInstance() {
   static CSingleton theInstance; // 唯一實例
   return theInstance;
  }
protected:
  // 需要默認的構造函數ctor
  // 因為要創建派生類,ctor 為 protected 類型
  CSingleton() { }
private:
  CSingleton(const CSingleton& o) { }
  CSingleton& operator=(const CSingleton& o) { }
};
void main()
{
  // 由於構造函數是私有類型的,所以這幾行編譯通不過:
  CSingleton x = CSingleton::GetInstance(); // error: private
                       // copy ctor!
  CSingleton y = CSingleton::GetInstance(); // error: private
                       // copy ctor!
  x = y;                  // error: private
                       // assignment!
  // 編譯器看到這樣的實例聲明會更滿意一些:
  CSingleton *p1 = CSingleton::GetInstance();
  CSingleton *p2 = p1->GetInstance();
  CSingleton & ref = * CSingleton::GetInstance();
}

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved