C++實現一個不能繼承的類

http://www.examda.com/ncre2/cpp/jichu/20090708/075336151.html

C#和Java都提供了一種機制讓一個類不能被繼承,如C#中的sealed關鍵字和Java的final關鍵字,然而C++程序員就沒這麼好命了。不過C++也可以模擬出這種效果,原理基於:子類的構造函數會自動調用父類的構造函數,同理析構函數也是一樣。如果父類的構造函數和析構函數被設爲私有的話,那麼子類就無法調用,也就達到了父類不可被繼承的目的了。原理很簡單,按此原理我也實作出一個自認爲很實用的工具類,在此獻下醜,歡迎大家批評:

  template< typename TDerive, typename TProvider >
  class  CFobidDeriveProviderBase
  {
  friend TDerive;
  friend TProvider;
  private:
  CFobidDeriveProviderBase(){}
  ~CFobidDeriveProviderBase(){}
  };
  /*
  * 提供禁止派生的功能,需要此功能的類可以從CFobidDeriveProvider派生,並將類名作爲模板參數傳遞
  */
  template< typename TDerive >
  class  CFobidDeriveProvider : virtual public CFobidDeriveProviderBase< TDerive, CFobidDeriveProvider<TDerive>>
  {
  public:
  CFobidDeriveProvider(){}
  ~CFobidDeriveProvider(){}
  };
  /*
  * 測試類,該類不可被繼承
  */
  class  CNoDerive : public CFobidDeriveProvider< CNoDerive >
  {
  public:
  CNoDerive(){}
  ~CNoDerive(){}
  void  Alert()
  {
  AtlMessageBox( NULL, _T("Alert") );
  }
  };
  之所以將繼承的結構分爲2層:CFobidDeriveProvider和CFobidDeriveProviderBase,主要是方便使用,用戶只需直接從CFobidDeriveProvider派生就可實現一個不可被繼承的類,而不需要虛擬繼承。
  若有類從CNoDerive派生:
  class  CSomeDerive : public CNoDerive
  {
  public:
  CSomeDerive(){}
  ~CSomeDerive(){}
  };
  CSomeDerive的構造函數調用過程如下:由於CFobidDeriveProvider是從CFobidDeriveProviderBase虛擬派生,在虛繼承出現的繼承層次中,總是在構造非虛基類之前構造虛基類,因而會跳過CNoDerive和CFobidDeriveProvider的構造函數而直接調用CFobidDeriveProviderBase的構造函數,但CSomeDerive不是CFobidDeriveProviderBase的友元,因此也無法調用CFobidDeriveProviderBase的私有構造函數。故而編譯錯誤。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章