最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析C++中類(lèi)的多重繼承

 更新時(shí)間:2015年09月22日 16:31:20   投稿:goldensun  
這篇文章主要介紹了深入解析C++中類(lèi)的多重繼承,包括多重繼承相關(guān)的二義性問(wèn)題,需要的朋友可以參考下

C++類(lèi)的多繼承
在前面的例子中,派生類(lèi)都只有一個(gè)基類(lèi),稱(chēng)為單繼承。除此之外,C++也支持多繼承,即一個(gè)派生類(lèi)可以有兩個(gè)或多個(gè)基類(lèi)。
多繼承容易讓代碼邏輯復(fù)雜、思路混亂,一直備受爭(zhēng)議,中小型項(xiàng)目中較少使用,后來(lái)的 Java、C#、PHP 等干脆取消了多繼承。想快速學(xué)習(xí)C++的讀者可以不必細(xì)讀。
多繼承的語(yǔ)法也很簡(jiǎn)單,將多個(gè)基類(lèi)用逗號(hào)隔開(kāi)即可。例如已聲明了類(lèi)A、類(lèi)B和類(lèi)C,那么可以這樣來(lái)聲明派生類(lèi)D:

class D: public A, private B, protected C{
 //類(lèi)D新增加的成員
}


D是多繼承的派生類(lèi),它以共有的方式繼承A類(lèi),以私有的方式繼承B類(lèi),以保護(hù)的方式繼承C類(lèi)。D根據(jù)不同的繼承方式獲取A、B、C中的成員,確定各基類(lèi)的成員在派生類(lèi)中的訪問(wèn)權(quán)限。
多繼承下的構(gòu)造函數(shù)

多繼承派生類(lèi)的構(gòu)造函數(shù)和單繼承類(lèi)基本相同,只是要包含多個(gè)基類(lèi)構(gòu)造函數(shù)。如:

D類(lèi)構(gòu)造函數(shù)名(總參數(shù)表列): A構(gòu)造函數(shù)(實(shí)參表列), B類(lèi)構(gòu)造函數(shù)(實(shí)參表列), C類(lèi)構(gòu)造函數(shù)(實(shí)參表列){
 新增成員初始化語(yǔ)句
}


各基類(lèi)的排列順序任意。

派生類(lèi)構(gòu)造函數(shù)的執(zhí)行順序同樣為:先調(diào)用基類(lèi)的構(gòu)造函數(shù),再調(diào)用派生類(lèi)構(gòu)造函數(shù)?;?lèi)構(gòu)造函數(shù)的調(diào)用順序是按照聲明派生類(lèi)時(shí)基類(lèi)出現(xiàn)的順序。

下面的定義了兩個(gè)基類(lèi),BaseA類(lèi)和BaseB類(lèi),然后用多繼承的方式派生出Sub類(lèi)。

#include <iostream>
using namespace std;
//基類(lèi)
class BaseA{
protected:
 int a;
 int b;
public:
 BaseA(int, int);
};
BaseA::BaseA(int a, int b): a(a), b(b){}
//基類(lèi)
class BaseB{
protected:
 int c;
 int d;
public:
 BaseB(int, int);
};
BaseB::BaseB(int c, int d): c(c), d(d){}
//派生類(lèi)
class Sub: public BaseA, public BaseB{
private:
 int e;
public:
 Sub(int, int, int, int, int);
 void display();
};
Sub::Sub(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), e(e){}
void Sub::display(){
 cout<<"a="<<a<<endl;
 cout<<"b="<<b<<endl;
 cout<<"c="<<c<<endl;
 cout<<"d="<<d<<endl;
 cout<<"e="<<e<<endl;
}
int main(){
 (new Sub(1, 2, 3, 4, 5)) -> display();
 return 0;
}

運(yùn)行結(jié)果:

a=1
b=2
c=3
d=4
e=5

從基類(lèi)BaseA和BaseB繼承來(lái)的成員變量,在 Sub::display() 中都可以訪問(wèn)。
命名沖突

當(dāng)兩個(gè)基類(lèi)中有同名的成員時(shí),就會(huì)產(chǎn)生命名沖突,這時(shí)不能直接訪問(wèn)該成員,需要加上類(lèi)名和域解析符。

假如在基類(lèi)BaseA和BaseB中都有成員函數(shù) display(),那么下面的語(yǔ)句是錯(cuò)誤的:

Sub obj;
obj.display();


由于BaseA和BaseB中都有display(),系統(tǒng)將無(wú)法判定到底要調(diào)用哪一個(gè)類(lèi)的函數(shù),所以報(bào)錯(cuò)。

應(yīng)該像下面這樣加上類(lèi)名和域解析符:

Sub obj;
obj.BaseA::display();
obj.BaseB::display();


通過(guò)這個(gè)舉例可以發(fā)現(xiàn):在多重繼承時(shí),從不同的基類(lèi)中會(huì)繼承一些重復(fù)的數(shù)據(jù)。如果有多個(gè)基類(lèi),問(wèn)題會(huì)更突出,所以在設(shè)計(jì)派生類(lèi)時(shí)要細(xì)致考慮其數(shù)據(jù)成員,盡量減少數(shù)據(jù)冗余。

C++多重繼承的二義性問(wèn)題
多重繼承可以反映現(xiàn)實(shí)生活中的情況,能夠有效地處理一些較復(fù)雜的問(wèn)題,使編寫(xiě)程序具有靈活性,但是多重繼承也引起了一些值得注意的問(wèn)題,它增加了程序的復(fù)雜度,使 程序的編寫(xiě)和維護(hù)變得相對(duì)困難,容易出錯(cuò)。其中最常見(jiàn)的問(wèn)題就是繼承的成員同名而產(chǎn)生的二義性(ambiguous)問(wèn)題。

如果類(lèi)A和類(lèi)B中都有成員函數(shù)display和數(shù)據(jù)成員a,類(lèi)C是類(lèi)A和類(lèi)B的直接派生類(lèi)。分別討論下列3種情況。

1) 兩個(gè)基類(lèi)有同名成員

代碼如下所示:

class A
{
public:
 int a;
 void display();
};
class B
{
public:
 int a;
 void display ();
};
class C: public A, public B
{
public:
 int b;
 void show();
};

如果在main函數(shù)中定義C類(lèi)對(duì)象cl,并調(diào)用數(shù)據(jù)成員a和成員函數(shù)display :

 C cl;
 cl.a=3;
 cl.display();


由于基類(lèi)A和基類(lèi)B都有數(shù)據(jù)成員a和成員函數(shù)display,編譯系統(tǒng)無(wú)法判別要訪問(wèn)的是哪一個(gè)基類(lèi)的成員,因此程序編譯出錯(cuò)。那么,應(yīng)該怎樣解決這個(gè)問(wèn)題呢?可以用基類(lèi)名來(lái)限定:

 cl.A::a=3; //引用cl對(duì)象中的基類(lèi)A的數(shù)據(jù)成員a
 cl.A::display(); //調(diào)用cl對(duì)象中的基類(lèi)A的成員函數(shù)display

如果是在派生類(lèi)C中通過(guò)派生類(lèi)成員函數(shù)show訪問(wèn)基類(lèi)A的display和a,可以不 必寫(xiě)對(duì)象名而直接寫(xiě)

 A::a = 3; //指當(dāng)前對(duì)象
 A::display();

2) 兩個(gè)基類(lèi)和派生類(lèi)三者都有同名成員

將上面的C類(lèi)聲明改為:

 class C: public A, public B
 {
  int a;
  void display();
 };


如果在main函數(shù)中定義C類(lèi)對(duì)象cl,并調(diào)用數(shù)據(jù)成員a和成員函數(shù)display:

 C cl;
 cl.a = 3;
 cl.display();


此時(shí),程序能通過(guò)編譯,也可以正常運(yùn)行。請(qǐng)問(wèn):執(zhí)行時(shí)訪問(wèn)的是哪一個(gè)類(lèi)中的成員?答案是:訪問(wèn)的是派生類(lèi)C中的成員。規(guī)則是:基類(lèi)的同名成員在派生類(lèi)中被屏蔽,成為“不可見(jiàn)”的,或者說(shuō),派生類(lèi)新增加的同名成員覆蓋了基類(lèi)中的同名成員。因此如果在定義派生類(lèi)對(duì)象的模塊中通過(guò)對(duì)象名訪問(wèn)同名的成員,則訪問(wèn)的是派生類(lèi)的成員。請(qǐng)注意:不同的成員函數(shù),只有在函數(shù)名和參數(shù)個(gè)數(shù)相同、類(lèi)型相匹配的情況下才發(fā)生同名覆蓋,如果只有函數(shù)名相同而參數(shù)不同,不會(huì)發(fā)生同名覆蓋,而屬于函數(shù)重載。

有些讀者可能對(duì)同名覆蓋感到不大好理解。為了說(shuō)明問(wèn)題,舉個(gè)例子,例如把中國(guó)作為基類(lèi),四川則是中國(guó)的派生類(lèi),成都則是四川的派生類(lèi)?;?lèi)是相對(duì)抽象的,派生類(lèi)是相對(duì)具體的,基類(lèi)處于外層,具有較廣泛的作用域,派生類(lèi)處于內(nèi)層,具有局部的作用域。若“中國(guó)”類(lèi)中有平均溫度這一屬性,四川和成都也都有平均溫度這一屬性,如果沒(méi)有四川和成都這兩個(gè)派生類(lèi),談平均溫度顯然是指全國(guó)平均溫度。如果在四川,談?wù)摦?dāng)?shù)氐钠骄鶞囟蕊@然是指四川的平均溫度;如果在成都,談?wù)摦?dāng)?shù)氐钠骄鶞囟蕊@然是指成都的平均溫度。這就是說(shuō),全國(guó)的“平均溫度”在四川省被四川的“平均溫度”屏蔽了,或者說(shuō),四川的“平均溫度”在當(dāng)?shù)仄帘瘟巳珖?guó)的“平均溫度”。四川人最關(guān)心的是四川的溫度,當(dāng)然不希望用全國(guó)溫度覆蓋四川的平均溫度。

如果在四川要查全國(guó)平均溫度,一定要聲明:我要查的是全國(guó)的平均溫度。同樣,要在派生類(lèi)外訪問(wèn)基類(lèi)A中的成員,應(yīng)指明作用域A,寫(xiě)成以下形式:

 cl.A::a=3; //表示是派生類(lèi)對(duì)象cl中的基類(lèi)A中的數(shù)據(jù)成員a
 cl.A::display(); //表示是派生類(lèi)對(duì)象cl中的基類(lèi)A中的成員函數(shù)display

3) 類(lèi)A和類(lèi)B是從同一個(gè)基類(lèi)派生的

代碼如下所示:

class N
{
public:
 int a;
 void display(){ cout<<"A::a="<<a<<endl; }
};
class A: public N
{
public:
 int al;
};
class B: public N
{
public:
 int a2;
};
class C: public A, public B
{
public:
 int a3;
 void show(){ cout<<"a3="<<a3<<endl; }
}
int main()
{
 C cl; //定義C類(lèi)對(duì)象cl
 // 其他代碼
}

在類(lèi)A和類(lèi)B中雖然沒(méi)有定義數(shù)據(jù)成員a和成員函數(shù)display,但是它們分別從類(lèi)N繼承了數(shù)據(jù)成員a和成員函數(shù)display,這樣在類(lèi)A和類(lèi)B中同時(shí)存在著兩個(gè)同名的數(shù)據(jù)成員a和成員函數(shù)display。它們是N類(lèi)成員的拷貝。類(lèi)A和類(lèi)B中的數(shù)據(jù)成員a代表兩個(gè)不同的存儲(chǔ)單元,可以分別存放不同的數(shù)據(jù)。在程序中可以通過(guò)類(lèi)A和類(lèi)B的構(gòu)造函數(shù)去調(diào)用基類(lèi)N的構(gòu)造函數(shù),分別對(duì)類(lèi)A和類(lèi)B的數(shù)據(jù)成員a初始化。

怎樣才能訪問(wèn)類(lèi)A中從基類(lèi)N繼承下來(lái)的成員呢?顯然不能用

 cl.a = 3; cl.display();



 cl.N::a = 3; cl. N::display();


因?yàn)檫@樣依然無(wú)法區(qū)別是類(lèi)A中從基類(lèi)N繼承下來(lái)的成員,還是類(lèi)B中從基類(lèi)N繼承下來(lái)的成員。應(yīng)當(dāng)通過(guò)類(lèi)N的直接派生類(lèi)名來(lái)指出要訪問(wèn)的是類(lèi)N的哪一個(gè)派生類(lèi)中的基類(lèi)成員。如

 cl.A::a=3; cl.A::display(); //要訪問(wèn)的是類(lèi)N的派生類(lèi)A中的基類(lèi)成員

相關(guān)文章

  • C語(yǔ)言動(dòng)態(tài)內(nèi)存管理深入探討

    C語(yǔ)言動(dòng)態(tài)內(nèi)存管理深入探討

    動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語(yǔ)言中動(dòng)態(tài)內(nèi)存的管理
    2022-06-06
  • C++/JAVA/C#子類(lèi)調(diào)用父類(lèi)函數(shù)情況總結(jié)

    C++/JAVA/C#子類(lèi)調(diào)用父類(lèi)函數(shù)情況總結(jié)

    今天小編就為大家分享一篇關(guān)于C++/JAVA/C#子類(lèi)調(diào)用父類(lèi)函數(shù)情況總結(jié),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • C語(yǔ)言算術(shù)運(yùn)算符整理

    C語(yǔ)言算術(shù)運(yùn)算符整理

    算術(shù)運(yùn)算符用于各類(lèi)數(shù)值運(yùn)算,包括加(+)、減(-)、乘(*)、除(/)、求余(或稱(chēng)模運(yùn)算,%)、自增(++)、自減(--)共七種
    2023-03-03
  • C++深入探究哈希表如何封裝出unordered_set和unordered_map

    C++深入探究哈希表如何封裝出unordered_set和unordered_map

    哈希表是一種根據(jù)關(guān)鍵碼去尋找值的數(shù)據(jù)映射結(jié)構(gòu),該結(jié)構(gòu)通過(guò)把關(guān)鍵碼映射的位置去尋找存放值的地方,說(shuō)起來(lái)可能感覺(jué)有點(diǎn)復(fù)雜,我想我舉個(gè)例子你就會(huì)明白了,最典型的的例子就是字典
    2022-06-06
  • C++ 兩個(gè)vector對(duì)象拼接方式

    C++ 兩個(gè)vector對(duì)象拼接方式

    這篇文章主要介紹了C++ 兩個(gè)vector對(duì)象拼接方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • MFC自定義消息的實(shí)現(xiàn)方法

    MFC自定義消息的實(shí)現(xiàn)方法

    這篇文章主要介紹了MFC自定義消息的實(shí)現(xiàn)方法,通過(guò)該示例可以更好的理解MFC的消息封裝機(jī)制,以便更加靈活的打造個(gè)性化的windows應(yīng)用程序,需要的朋友可以參考下
    2014-07-07
  • C/C++中獲取數(shù)組長(zhǎng)度的方法示例

    C/C++中獲取數(shù)組長(zhǎng)度的方法示例

    這篇文章主要介紹了C/C++中獲取數(shù)組長(zhǎng)度的方法,很實(shí)用的一種方法,需要的朋友可以參考下
    2014-08-08
  • C++ 逗號(hào)運(yùn)算符的具體使用

    C++ 逗號(hào)運(yùn)算符的具體使用

    本文主要介紹了C++ 逗號(hào)運(yùn)算符的具體使用,使用逗號(hào)運(yùn)算符是為了把幾個(gè)表達(dá)式放在一起,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • C++隱式轉(zhuǎn)換與顯式轉(zhuǎn)換詳解

    C++隱式轉(zhuǎn)換與顯式轉(zhuǎn)換詳解

    這篇文章主要介紹了C++隱式轉(zhuǎn)換與顯式轉(zhuǎn)換,關(guān)于類(lèi)型轉(zhuǎn)換,通常是隱式轉(zhuǎn)換或者強(qiáng)制轉(zhuǎn)換,C++提供了一些能夠顯式表示轉(zhuǎn)換的運(yùn)算符,能夠更好的規(guī)避一些風(fēng)險(xiǎn)和錯(cuò)誤,需要的朋友可以參考下
    2026-02-02
  • C++ 中消息隊(duì)列函數(shù)實(shí)例詳解

    C++ 中消息隊(duì)列函數(shù)實(shí)例詳解

    這篇文章主要介紹了C++ 中消息隊(duì)列函數(shù)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06

最新評(píng)論

绥棱县| 积石山| 营山县| 开阳县| 柘城县| 永德县| 东平县| 邵武市| 九龙坡区| 舒兰市| 武穴市| 崇州市| 全州县| 托克逊县| 庄河市| 错那县| 博客| 礼泉县| 东阳市| 哈巴河县| 财经| 兴宁市| 彭泽县| 登封市| 黄龙县| 临猗县| 尼玛县| 咸丰县| 富蕴县| 吉林省| 龙游县| 黔东| 丹凤县| 青阳县| 太仓市| 台中县| 重庆市| 北海市| 泰兴市| 宜城市| 杂多县|