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

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

C++的虛繼承

2019-11-06 07:23:56
字體:
供稿:網(wǎng)友

本文

1.為什么要引入虛擬繼承

虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現(xiàn)的。如:類D繼承自類B1、B2,而類B1、B2都繼承自類A,因此在類D中兩次出現(xiàn)類A中的變量和函數(shù)。為了節(jié)省內(nèi)存空間,可以將B1、B2對A的繼承定義為虛擬繼承,而A就成了虛擬基類。實現(xiàn)的代碼如下:

class A

class B1:public virtual A;

class B2:public virtual A;

class D:public B1,public B2;

虛擬繼承在一般的應(yīng)用中很少用到,所以也往往被忽視,這也主要是因為在C++中,多重繼承是不推薦的,也并不常用,而一旦離開了多重繼承,虛擬繼承就完全失去了存在的必要因為這樣只會降低效率和占用更多的空間。

 

2.引入虛繼承和直接繼承會有什么區(qū)別呢

由于有了間接性和共享性兩個特征,所以決定了虛繼承體系下的對象在訪問時必然會在時間和空間上與一般情況有較大不同。

2.1時間:在通過繼承類對象訪問虛基類對象中的成員(包括數(shù)據(jù)成員和函數(shù)成員)時,都必須通過某種間接引用來完成,這樣會增加引用尋址時間(就和虛函數(shù)一樣),其實就是調(diào)整this指針以指向虛基類對象,只不過這個調(diào)整是運行時間接完成的。

2.2空間:由于共享所以不必要在對象內(nèi)存中保存多份虛基類子對象的拷貝,這樣較之多繼承節(jié)省空間。虛擬繼承與普通繼承不同的是,虛擬繼承可以防止出現(xiàn)diamond繼承時,一個派生類中同時出現(xiàn)了兩個基類的子對象。也就是說,為了保證這一點,在虛擬繼承情況下,基類子對象的布局是不同于普通繼承的。因此,它需要多出一個指向基類子對象的指針。

 

3.筆試,面試中常考的C++虛擬繼承的知識點

第一種情況:         第二種情況:          第三種情況            第四種情況:class a           class a              class a              class a{              {                {                 {    virtual void func();      virtual void func();       virtual void func();        virtual void func();};              };                  char x;              char x;class b:public virtual a   class b :public a           };                };{              {                class b:public virtual a      class b:public a    virtual void foo();        virtual void foo();     {                 {};              };                  virtual void foo();        virtual void foo();                               };                };

如果對這四種情況分別求sizeof(a),  sizeof(b)。結(jié)果是什么樣的呢?下面是輸出結(jié)果:(在vc6.0中運行)第一種:4,12 第二種:4,4第三種:8,16第四種:8,8

想想這是為什么呢?

因為每個存在虛函數(shù)的類都要有一個4字節(jié)的指針指向自己的虛函數(shù)表,所以每種情況的類a所占的字節(jié)數(shù)應(yīng)該是沒有什么問題的,那么類b的字節(jié)數(shù)怎么算呢?看“第一種”和“第三種”情況采用的是虛繼承,那么這時候就要有這樣的一個指針vptr_b_a,這個指針叫虛類指針,也是四個字節(jié);還要包括類a的字節(jié)數(shù),所以類b的字節(jié)數(shù)就求出來了。而“第二種”和“第四種”情況則不包括vptr_b_a這個指針,這回應(yīng)該木有問題了吧。

第一個:vfptr(b:foo)+vbptr+vfptr(a:func)=12第二個:vfptr(a:func, b:foo)=4(兩個類大小為1,內(nèi)存對齊為4)第三個:vfptr(b:foo)+vbptr+vfptr(a:func)+x(對齊為四個字節(jié))=16第四個:vfptr(a:func, b:foo)+x(對齊為四個字節(jié))=8

 

4.c++重載、覆蓋、隱藏的區(qū)別和執(zhí)行方式

既然說到了繼承的問題,那么不妨討論一下經(jīng)常提到的重載,覆蓋和隱藏4.1成員函數(shù)被重載的特征(1)相同的范圍(在同一個類中); (2)函數(shù)名字相同; (3)參數(shù)不同; (4)virtual 關(guān)鍵字可有可無。 4.2“覆蓋”是指派生類函數(shù)覆蓋基類函數(shù),特征是:(1)不同的范圍(分別位于派生類與基類); (2)函數(shù)名字相同; (3)參數(shù)相同; (4)基類函數(shù)必須有virtual 關(guān)鍵字。 4.3“隱藏”是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),特征是:

(1)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同,此時,不論有無virtual關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。 (2)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)相同,但是基類函數(shù)沒有virtual 關(guān)鍵字。此時,基類的函數(shù)被隱藏(注意別與覆蓋混淆)。

小結(jié):說白了就是如果派生類和基類的函數(shù)名和參數(shù)都相同,且有virtual關(guān)鍵字,屬于覆蓋,這是可以理解的吧,完全一樣當(dāng)然要覆蓋了;如果只是函數(shù)名相同,參數(shù)并不相同,則屬于隱藏。

4.4 三種情況怎么執(zhí)行:

4.4.1 重載:看參數(shù)。

4.4.2 隱藏:用什么就調(diào)用什么。

4.4.3 覆蓋:調(diào)用派生類。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 巴楚县| 吉安市| 甘德县| 大同县| 德惠市| 贵德县| 常宁市| 迁安市| 化德县| 嘉兴市| 南安市| 宜昌市| 柏乡县| 商城县| 信宜市| 南川市| 哈尔滨市| 巢湖市| 海原县| 崇州市| 镇远县| 麻城市| 堆龙德庆县| 沅陵县| 房山区| 咸丰县| 长白| 平陆县| 睢宁县| 如皋市| 厦门市| 宁都县| 甘孜县| 广河县| 静宁县| 重庆市| 茶陵县| 桃江县| 邻水| 宁强县| 城步|