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

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

菱形虛擬繼承的深入剖析

2019-11-08 19:50:12
字體:
供稿:網(wǎng)友

繼承是面向?qū)ο笳Z言的一大特性,在C++中既有單繼承,當(dāng)然也會存在多繼承。那么多繼承是怎么實現(xiàn)的及多繼承的一些缺點,將是這篇博客想要說的內(nèi)容。

多繼承最典型的一個例子就是菱形繼承,那什么又是菱形繼承呢?就是有兩個子類分別繼承一個父類,而有存在一個子類同時這兩個子類。圖示如下。 這里寫圖片描述

class A{public: int a;};class B : public A{public : int b;};class C : public A{public: int c;};class D : public B, public C{public: int d;};int main(){ D d; system("pause"); return 0;}

當(dāng)我們模擬出菱形繼承想給a賦值時,就會發(fā)現(xiàn)一個問題,我們到底是從哪個類去訪問的BaseClass中的a?這時就會產(chǎn)生二義性。也就是說在內(nèi)存中會出現(xiàn)兩個BaseClass,結(jié)構(gòu)圖如下。

結(jié)構(gòu)圖

內(nèi)存中

代碼運行后調(diào)監(jiān)視窗口如上,可明顯看到d中存在了兩個a,這也會存在數(shù)據(jù)冗余的問題。那怎么去解決這個問題?此時,C++又提出了另一個新概念——虛擬繼承。虛擬繼承使得在繼承間接共同基類的時候只保留一份成員。接下來的篇幅將會說明虛擬繼承的實現(xiàn)。

class A{public: int a;};class B : virtual public A{public : int b;};class C : virtual public A{public: int c;};class D : public B, public C{public: int d;};int main(){ D d; d.B::a = 0; d.C::a = 1; d.B::b = 2; d.C::c = 3; d.D::d = 4; cout << (sizeof(d)) << endl; system("pause"); return 0;}

運行上述代碼后,在內(nèi)存中會出現(xiàn)以下的情形,如下圖。 這里寫圖片描述

原來大小為20的d如今變成了24,按理說當(dāng)我們采用了虛擬繼承,解決了數(shù)據(jù)冗余問題,所占的空間應(yīng)該也會變小,但如今反而變大了,這是怎么回事呢?

我們在細(xì)看第一行和第三行,發(fā)現(xiàn)了這兩個數(shù)字比較接近,仔細(xì)看更像是一個地址。于是,在內(nèi)存中查看會發(fā)現(xiàn)如下圖所示的情形。

這里寫圖片描述

在這兩個內(nèi)存緊挨著的地方,出現(xiàn)了一個“14”和“0c”,也就是說在這個地方存了這兩個數(shù)字。那么我們就可以猜測一下,在虛擬繼承中,菱形繼承的結(jié)構(gòu)是如下圖的。

這里寫圖片描述

BaseClass并不是按照我們所想象那樣存在最上面的,而是存放在最底下,而原來存BaseClass的地方存了兩個“數(shù)字”。仔細(xì)觀察,不難發(fā)現(xiàn)這兩個數(shù)字是距離BaseClass的位移,也就是我們所說的偏移量。

其實,講到這里的時候,大家應(yīng)該也就明白了,在虛擬繼承中是通過存儲基類的偏移量來解決數(shù)據(jù)冗余的問題,以空間換時間解決菱形繼承存在的問題。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 金华市| 永仁县| 古田县| 祁阳县| 平舆县| 武强县| 来宾市| 泾阳县| 含山县| 大同县| 北辰区| 海兴县| 阿拉尔市| 辽宁省| 灵石县| 娱乐| 绩溪县| 宽甸| 石门县| 东台市| 庆城县| 庆元县| 阿合奇县| 丹江口市| 新沂市| 炎陵县| 邢台市| 大庆市| 启东市| 靖江市| 兴安盟| 本溪市| 华蓥市| 田林县| 成武县| 策勒县| 汾阳市| 龙游县| 丰台区| 阿拉善右旗| 滨海县|