国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++設(shè)計(jì)類不能被繼承的方法實(shí)例講解

2020-01-26 15:40:46
字體:
供稿:網(wǎng)友

首先想到的是在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è)思路,可以寫出如下的代碼:

復(fù)制代碼 代碼如下:

///////////////////////////////////////////////////////////////////////
// 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)看如下代碼:

復(fù)制代碼 代碼如下:

///////////////////////////////////////////////////////////////////////
// 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í),卻不同通過編譯。

復(fù)制代碼 代碼如下:

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)。

復(fù)制代碼 代碼如下:

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
{
};

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 申扎县| 枣强县| 仁化县| 朝阳市| 景东| 宝山区| 伊川县| 龙江县| SHOW| 龙江县| 邵阳市| 成安县| 内黄县| 永宁县| 云安县| 寿阳县| 西峡县| 噶尔县| 准格尔旗| 玛多县| 黔东| 视频| 五峰| 融水| 新田县| 莱芜市| 苏尼特左旗| 新闻| 论坛| 枣庄市| 库车县| 浪卡子县| 鸡西市| 罗山县| 陆河县| 威宁| 贵州省| 大宁县| 班戈县| 保康县| 吉安市|