C++設(shè)計類不能被繼承的方法實例講解
首先想到的是在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è)計要求。
C++11中已經(jīng)有了final關(guān)鍵字:它的作用是指定類的虛函數(shù)不能被該類的繼承類重寫(override),或者是指定一個類成為一個不能被繼承的類(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
{
};
相關(guān)文章
C語言實現(xiàn)學(xué)生成績管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生成績管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01c++ map索引不存在的key可能導(dǎo)致的后果分析
這篇文章主要介紹了c++ map索引不存在的key可能導(dǎo)致的后果分析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12