程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]
題目:用C++設(shè)計一個不能被繼承的類。
分析:這是Adobe公司2007年校園招聘的最新筆試題。這道題除了考察應(yīng)聘者的C++基本功底外,還能考察反應(yīng)能力,是一道很好的題目。
在Java中定義了關(guān)鍵字final,被final修飾的類不能被繼承。但在C++中沒有final這個關(guān)鍵字,要實現(xiàn)這個要求還是需要花費一些精力。
首先想到的是在C++?中,子類的構(gòu)造函數(shù)會自動調(diào)用父類的構(gòu)造函數(shù)。同樣,子類的析構(gòu)函數(shù)也會自動調(diào)用父類的析構(gòu)函數(shù)。要想一個類不能被繼承,我們只要把它的構(gòu)造函數(shù)和析構(gòu)函數(shù)都定義為私有函數(shù)。那么當(dāng)一個類試圖從它那繼承的時候,必然會由于試圖調(diào)用構(gòu)造函數(shù)、析構(gòu)函數(shù)而導(dǎo)致編譯錯誤。
可是這個類的構(gòu)造函數(shù)和析構(gòu)函數(shù)都是私有函數(shù)了,我們怎樣才能得到該類的實例呢?這難不倒我們,我們可以通過定義靜態(tài)來創(chuàng)建和釋放類的實例。基于這個思路,我們可以寫出如下的代碼:
/// // Define a class which can't be derived from /// class FinalClass1 { public:static FinalClass1* GetInstance(){return new FinalClass1;}static void DeleteInstance( FinalClass1* pInstance){delete pInstance;pInstance = 0;}private:FinalClass1() {}~FinalClass1() {} };這個類是不能被繼承,但在總覺得它和一般的類有些不一樣,使用起來也有點不方便。比如,我們只能得到位于堆上的實例,而得不到位于棧上實例。
能不能實現(xiàn)一個和一般類除了不能被繼承之外其他用法都一樣的類呢?辦法總是有的,不過需要一些技巧。請看如下代碼:
/// // Define a class which can't be derived from /// template <typename T> class MakeFinal {friend T;private:MakeFinal() {}~MakeFinal() {} };class FinalClass2 : virtual public MakeFinal<FinalClass2> { public:FinalClass2() {}~FinalClass2() {} };這個類使用起來和一般的類沒有區(qū)別,可以在棧上、也可以在堆上創(chuàng)建實例。盡管類MakeFinal<FinalClass2>的構(gòu)造函數(shù)和析構(gòu)函數(shù)都是私有的,但由于類FinalClass2是它的友元函數(shù),因此在FinalClass2中調(diào)用MakeFinal<FinalClass2>的構(gòu)造函數(shù)和析構(gòu)函數(shù)都不會造成編譯錯誤。
但當(dāng)我們試圖從FinalClass2繼承一個類并創(chuàng)建它的實例時,卻不同通過編譯。
class Try : public FinalClass2 { public:Try() {}~Try() {} };Try temp;由于類FinalClass2是從類MakeFinal<FinalClass2>虛繼承過來的,在調(diào)用Try的構(gòu)造函數(shù)的時候,會直接跳過FinalClass2而直接調(diào)用MakeFinal<FinalClass2>的構(gòu)造函數(shù)。非常遺憾的是,Try不是MakeFinal<FinalClass2>的友元,因此不能調(diào)用其私有的構(gòu)造函數(shù)。
基于上面的分析,試圖從FinalClass2繼承的類,一旦實例化,都會導(dǎo)致編譯錯誤,因此是FinalClass2不能被繼承。這就滿足了我們設(shè)計要求。
?
本文已經(jīng)收錄到《劍指Offer——名企面試官精講典型編程題》一書中,有改動,書中的分析講解更加詳細(xì)。歡迎關(guān)注。
博主何海濤對本博客文章享有版權(quán)。網(wǎng)絡(luò)轉(zhuǎn)載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯(lián)系。
總結(jié)
以上是生活随笔為你收集整理的程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员面试题精选100题(31)-从尾到
- 下一篇: 程序员面试题精选100题(33)-在O(