標籤:通過 void 靜態成員函數 one 虛擬 繼承 ati 模板類 關係
面試中可能遇到讓設計一個無法被繼承的類。最簡單的實現是將該類的建構函式設定為私人的,然後通過靜態成員函數調用私人建構函式執行個體化對象,這樣的類確實不可繼承,但是使用起來非常不方便,必須使用靜態成員執行個體化對象,而且Object Storage Service在堆中,無法像一個普通的類一樣的被使用。最佳的設計是結合私人構造函、友元、虛擬繼承實現。
一、簡單實現
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 };二、最佳實現
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 //};
關鍵點:
- 模板類NoneInherit類,建構函式和解構函式都設定為私人,模板參數T設定為友元,這樣友元類可以調用建構函式。例如FinalClass是NoneInherit的友元類,可以使用基類的私人建構函式和解構函式
- 虛擬繼承virtual是最關鍵的點。如果繼承時去掉virtual,FinalClass還是可以被繼承的,那麼為什麼需要使用虛擬繼承呢?因為在普通繼承中,每個類只是初始化自己的直接的基類。那意味著,如果不使用virtual,TestClass繼承Finalclass,由FinalClass再去調用NoneInherit類,由於FinalClass是NoneInHerit的基類,因此整個繼承沒有任何問題。由於FinalClass使用了虛擬繼承,在建立TestClass的時候,TestClass類的建構函式要負責虛基類NoneInherit類的構造,而NoneInherit的建構函式是私人的,友元關係也無法繼承,因此TestClass類沒有訪問的許可權。
面試:C++不可繼承類