天天看點

用C++設計一個不能被繼承的類

在java 中定義了關鍵字final,被final修飾的類不能被繼承。

首先想到的是在c++中,子類的構造函數會自動調用父類的構造函數。同樣,子類的析構函數也會自動調用父類的析構函數。要想一個類不能被繼承,隻要把它的構造函數和析構函數都定義為私有函數。那麼當一個類試圖從它那繼承的時候,必然會由于試圖調用構造函數、析構函數而導緻編譯錯誤。

可是這個類的構造函數和析構函數都是私有函數了,怎樣才能得到該類的執行個體呢?可以通過定義靜态來建立和釋放類的執行個體。基于這個思路,可以寫出如下的代碼:

用C++設計一個不能被繼承的類
用C++設計一個不能被繼承的類

這個類是不能被繼承,但在總覺得它和一般的類有些不一樣,使用起來也有點不友善。比如,隻能得到位于堆上的執行個體,而得不到位于棧上執行個體。

能不能實作一個和一般類除了不能被繼承之外其他用法都一樣的類呢?辦法總是有的,不過需要一些技巧。請看如下代碼:

用C++設計一個不能被繼承的類
用C++設計一個不能被繼承的類

這個類使用起來和一般的類沒有差別,可以在棧上、也可以在堆上建立執行個體。盡管類makefinal<finalclass2>的構造函數和析構函數都是私有的,但由于類finalclass2是它的友元函數,是以在finalclass2中調用makefinal<finalclass2>的構造函數和析構函數都不會造成編譯錯誤。

但當試圖從finalclass2繼承一個類并建立它的執行個體時,卻不同通過編譯。

用C++設計一個不能被繼承的類
用C++設計一個不能被繼承的類

由于類finalclass2是從類makefinal<finalclass2>虛繼承過來的,在調用try的構造函數的時候,會直接跳過finalclass2而直接調用makefinal<finalclass2>的構造函數。非常遺憾的是,try不是makefinal<finalclass2>的友元,是以不能調用其私有的構造函數。

基于上面的分析,試圖從finalclass2繼承的類,一旦執行個體化,都會導緻編譯錯誤,是以是finalclass2不能被繼承。這就滿足了設計要求。

用C++設計一個不能被繼承的類
用C++設計一個不能被繼承的類

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

http://www.cnblogs.com/luxiaoxun/archive/2013/06/07/3124948.html