C++多重繼承與虛繼承

多重繼承

一個簡單的例子(非虛擬)

class Top
{
    public: int a;
}; 
class Left : public Top
{ 
    public: int b;
}; 
class Right : public Top
{ 
    public: int c;
}; 
class Bottom : public Left, public Right
{ 
    public: int d;
};

使用UML圖覆旭,我們可以把這個層次結(jié)構(gòu)表示為:



注意Top被繼承了兩次框弛。這意味著類型Bottom的一個實例bottom將有兩個叫做a的元素(分別為bottom.Left::a 和 bottom.Right::a)韵卤。


Left脏款、Right 和 Bottom在內(nèi)存中是如何布局的辐宾,讓我們先看一個簡單的例子买猖。Left
和 Right擁有如下的結(jié)構(gòu):

Left Right
Top::a Top::a
left::b right::c

請注意第一個屬性是從Top繼承下來的刁笙。這意味著在下面兩條語句后

Left* left = new Left();
Top* top = left;

Left 和 Top指向了同一地址破花,我們可以把Left Object當成Top Object來使用(很明顯,Right與此也類似)疲吸。那Buttom呢座每?GCC的建議如下:

Buttom
Left::Top::a
Left::b
Right::Top::a
Right::c
Bottom::d

如果我們提升Bottom指針,會發(fā)生什么事呢摘悴?

Bottom* bottom = new Bottom();
Left* left = bottom;

這段代碼工作正常峭梳。我們可以把一個Bottom的對象當作一個Left對象來使用,因為兩個類的內(nèi)存部局是一樣的蹂喻。那么葱椭,如果將其提升為Right呢?會發(fā)生什么事口四?

Right* right = bottom;

為了執(zhí)行這條語句孵运,我們需要判斷指針的值以便讓它指向Bottom中對應的段。

Bottom
Left::Top::a
Left::b
right --> Right::Top::a
Right::c
Bottom::d

經(jīng)過這一步窃祝,我們可以像操作正常Right對象一樣使用right指針訪問bottom掐松。雖然,bottom與right現(xiàn)在指向兩個不同的內(nèi)存地址粪小。出于完整性的緣故大磺,思考一下執(zhí)行下面這條語句時會出現(xiàn)什么狀況。

Top* top = bottom;

是的探膊,什么也沒有杠愧。這條語句是有歧義的:編譯器將會報錯。

error: `Top' is an ambiguous base of `Bottom'

兩種方式可以避免這樣的歧義

Top* topL = (Left*) bottom;
Top* topR = (Right*) bottom;

執(zhí)行這兩條語句后逞壁,topL 和 left會指向同樣的地址流济,topR 和 right也會指向同樣的地址。


虛擬繼承

為了避免重復繼承Top腌闯,我們必須虛擬繼承Top:

class Top
{ 
    public: int a;
}; 
class Left : virtual public Top
{ 
    public: int b;
}; 
class Right : virtual public Top
{ 
    public: int c;
}; 
class Bottom : public Left, public Right
{ 
    public: int d;
};

這就得到了如下的層次結(jié)構(gòu):



雖然從程序員的角度看绳瘟,這也許更加的明顯和簡便,但從編譯器的角度看姿骏,這就變得非常的復雜糖声。重新考慮下Bottom的布局,可能是:

Bottom
Left::Top::a
Left::b
Right::c
Bottom::d

這個布局的優(yōu)點是,布局的第一部分與Left的布局重疊了蘸泻,這樣我們就可以很容易的通過一個Left指針訪問 Bottom類琉苇。


未完待續(xù)。悦施。并扇。
摘抄自 開源中國

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市抡诞,隨后出現(xiàn)的幾起案子穷蛹,更是在濱河造成了極大的恐慌,老刑警劉巖沐绒,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俩莽,死亡現(xiàn)場離奇詭異,居然都是意外死亡乔遮,警方通過查閱死者的電腦和手機扮超,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹋肮,“玉大人出刷,你說我怎么就攤上這事∨鞅纾” “怎么了馁龟?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漆魔。 經(jīng)常有香客問我坷檩,道長,這世上最難降的妖魔是什么改抡? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任矢炼,我火速辦了婚禮,結(jié)果婚禮上阿纤,老公的妹妹穿的比我還像新娘句灌。我一直安慰自己,他們只是感情好欠拾,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布胰锌。 她就那樣靜靜地躺著,像睡著了一般藐窄。 火紅的嫁衣襯著肌膚如雪资昧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天荆忍,我揣著相機與錄音榛搔,去河邊找鬼诺凡。 笑死,一個胖子當著我的面吹牛践惑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘶卧,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼尔觉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芥吟?” 一聲冷哼從身側(cè)響起侦铜,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钟鸵,沒想到半個月后钉稍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡棺耍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年贡未,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙袍。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡俊卤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出害幅,到底是詐尸還是另有隱情消恍,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布以现,位于F島的核電站狠怨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏邑遏。R本人自食惡果不足惜佣赖,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望无宿。 院中可真熱鬧茵汰,春花似錦、人聲如沸孽鸡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彬碱。三九已至豆胸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巷疼,已是汗流浹背晚胡。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人估盘。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓瓷患,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遣妥。 傳聞我的和親對象是個殘疾皇子擅编,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容