C++設(shè)計(jì)類不能被繼承的方法實(shí)例講解
首先想到的是在C++中,子類的構(gòu)造函數(shù)會(huì)自動(dòng)調(diào)用父類的構(gòu)造函數(shù)。同樣,子類的析構(gòu)函數(shù)也會(huì)自動(dòng)調(diào)用父類的析構(gòu)函數(shù)。要想一個(gè)類不能被繼承,只要把它的構(gòu)造函數(shù)和析構(gòu)函數(shù)都定義為私有函數(shù)。那么當(dāng)一個(gè)類試圖從它那繼承的時(shí)候,必然會(huì)由于試圖調(diào)用構(gòu)造函數(shù)、析構(gòu)函數(shù)而導(dǎo)致編譯錯(cuò)誤。
可是這個(gè)類的構(gòu)造函數(shù)和析構(gòu)函數(shù)都是私有函數(shù)了,怎樣才能得到該類的實(shí)例呢?可以通過定義靜態(tài)來創(chuàng)建和釋放類的實(shí)例?;谶@個(gè)思路,可以寫出如下的代碼:
///////////////////////////////////////////////////////////////////////
// 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() {}
};
這個(gè)類是不能被繼承,但在總覺得它和一般的類有些不一樣,使用起來也有點(diǎn)不方便。比如,只能得到位于堆上的實(shí)例,而得不到位于棧上實(shí)例。
能不能實(shí)現(xiàn)一個(gè)和一般類除了不能被繼承之外其他用法都一樣的類呢?辦法總是有的,不過需要一些技巧。請(qǐng)看如下代碼:
///////////////////////////////////////////////////////////////////////
// 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() {}
};
這個(gè)類使用起來和一般的類沒有區(qū)別,可以在棧上、也可以在堆上創(chuàng)建實(shí)例。盡管類MakeFinal<FinalClass2>的構(gòu)造函數(shù)和析構(gòu)函數(shù)都是私有的,但由于類FinalClass2是它的友元函數(shù),因此在FinalClass2中調(diào)用MakeFinal<FinalClass2>的構(gòu)造函數(shù)和析構(gòu)函數(shù)都不會(huì)造成編譯錯(cuò)誤。
但當(dāng)試圖從FinalClass2繼承一個(gè)類并創(chuàng)建它的實(shí)例時(shí),卻不同通過編譯。
class Try : public FinalClass2
{
public :
Try() {}
~Try() {}
};
Try temp;
由于類FinalClass2是從類MakeFinal<FinalClass2>虛繼承過來的,在調(diào)用Try的構(gòu)造函數(shù)的時(shí)候,會(huì)直接跳過FinalClass2而直接調(diào)用MakeFinal<FinalClass2>的構(gòu)造函數(shù)。非常遺憾的是,Try不是MakeFinal<FinalClass2>的友元,因此不能調(diào)用其私有的構(gòu)造函數(shù)。
基于上面的分析,試圖從FinalClass2繼承的類,一旦實(shí)例化,都會(huì)導(dǎo)致編譯錯(cuò)誤,因此是FinalClass2不能被繼承。這就滿足了設(shè)計(jì)要求。
C++11中已經(jīng)有了final關(guān)鍵字:它的作用是指定類的虛函數(shù)不能被該類的繼承類重寫(override),或者是指定一個(gè)類成為一個(gè)不能被繼承的類(final class)。
struct A
{
virtual void foo() final;
};
struct B final : A
{
void foo(); // Error: foo cannot be overridden as it's final in A
};
struct C : B // Error: B is final
{
};
上一篇:C++訪問注冊(cè)表獲取已安裝軟件信息列表示例代碼
欄 目:C語言
本文標(biāo)題:C++設(shè)計(jì)類不能被繼承的方法實(shí)例講解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3885.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10千萬不要被階乘嚇倒
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10C語言 解決不用+、-、&#215;、&#247;數(shù)字運(yùn)算符做加法
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁面的局部加載