程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 探討C++實現一個不可被繼承的類

探討C++實現一個不可被繼承的類

編輯:關於C++

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的私有構造函數。故而編譯錯誤。

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