面試:C++不可繼承類

  面試中可能遇到讓設計一個沒法被繼承的類。最簡單的實現是將該類的構造函數設置爲私有的,而後經過靜態成員函數調用私有構造函數實例化對象,這樣的類確實不可繼承,可是使用起來很是不方便,必須使用靜態成員實例化對象,並且對象存儲在堆中,沒法像一個普通的類同樣的被使用。最佳的設計是結合私有構造函、友元、虛擬繼承實現。面試

1、簡單實現

 1 class Simple{
 2 private:
 3     Simple(){};
 4     ~Simple(){}
 5 private:
 6     static Simple* getInstance(){
 7         return new Simple();
 8     }
 9     static void deleteInstance(Simple* instance){
10         delete instance;
11     }
12 };

2、最佳實現

 1 template<typename T>
 2 class NoneInherit {
 3     friend T;
 4 private:
 5     NoneInherit() {
 6     }
 7     ~NoneInherit() {
 8     }
 9 };
10 
11 class Finalclass: virtual public NoneInherit<Finalclass> {
12 public:
13     Finalclass() {
14     }
15     ~Finalclass() {
16     }
17 };
18 
19 //class TestClass: public Finalclass {
20 //};

關鍵點:函數

  1. 模板類NoneInherit類,構造函數和析構函數都設置爲私有,模板參數T設置爲友元,這樣友元類能夠調用構造函數。例如FinalClass是NoneInherit的友元類,能夠使用基類的私有構造函數和析構函數
  2. 虛擬繼承virtual是最關鍵的點。若是繼承時去掉virtual,FinalClass仍是能夠被繼承的,那麼爲何須要使用虛擬繼承呢?由於在普通繼承中,每一個類只是初始化本身的直接的基類。那意味着,若是不使用virtual,TestClass繼承Finalclass,由FinalClass再去調用NoneInherit類,因爲FinalClass是NoneInHerit的基類,所以整個繼承沒有任何問題。因爲FinalClass使用了虛擬繼承,在建立TestClass的時候,TestClass類的構造函數要負責虛基類NoneInherit類的構造,而NoneInherit的構造函數是私有的,友元關係也沒法繼承,所以TestClass類沒有訪問的權限。
相關文章
相關標籤/搜索