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

首頁 > 學院 > 開發設計 > 正文

菱形繼承—虛繼承

2019-11-08 19:45:14
字體:
來源:轉載
供稿:網友

今天小生學習了虛繼承,做了一下總結,不足之處請多多批評指正: 首先,菱形繼承有一個父類例如class AA,再有兩個子類分別繼承AA,如class BB:public AA、class CC:public AA,最后,將BB、CC作為父類繼承給子類DD,這就形成了菱形繼承。請看以下代碼: class AA { public: int _aa; }; class BB: public AA { public: int _bb; }; class CC: public AA { public: int _cc; }; class DD:public BB,public CC { public: int _dd; }; AA類中包含一個int變量_aa,BB、CC分別繼承了AA,各自又都有一個int型變量,DD繼承了BB和CC,它自己又另外有一個自己的int型變量,請往下看: void Test1() { DD d; d._aa = 1; d._bb = 2; d._cc = 3; d._dd = 4; } 在Test1中定義了一個DD類型的d,分別給d._aa、d._bb、d._cc,d._dd賦值,運行代碼發現出現了以下錯誤:這里寫圖片描述 對_aa的訪問不明確,為什么呢?是因為d中包含了一個BB類型和一個CC類型,而它們都繼承了AA類型,所以d中包含了兩個_aa,當我們直接用d._aa訪問時,編譯器不知道我們訪問的是哪一個,所以出錯,這既是菱形繼承的二義性,堅決這個問題的一種方法是指定類域,如下圖這里寫圖片描述代碼: 上圖代碼運行后得到右面的結果,大家可以看到,我們給_aa賦值時指定了給BB類型 中的_aa賦值,而CC中的_aa并不會發生變化。這種方法雖然解決了菱形繼承的二義性,確沒有解決代碼冗余的問題,下面給大家介紹另一種方法虛繼承,它能夠同時解決了這兩個問題。虛繼承中我們用到了關鍵字virtual,請看以下代碼: class BB:virtual public AA { public: int _bb; }; class CC:virtual public AA { public: int _cc; }; class DD:public BB,public CC { public: int _dd; }; BB與CC在繼承AA時在public AA前面加了virtual這個關鍵字,這樣我們再運行下面這段代碼時發現原來的錯誤沒有了。 void Test1()

DD d;d._aa = 1;d._bb = 2;d._cc = 3;d._dd = 4;

} 這是為什么呢,因為加上virtual后我,DD型變量d在內存中存儲方式方式的變化,下圖為大家展示了二者的不同: 這里寫圖片描述 大家從內存中可以看到前后發生的變化,_aa只有一個了,所以解決了二義性和代碼冗余的問題,大家可能會覺得這里占用的內存反而用的多了,并且_bb、_CC上面都多了一個地址,那我們看看這兩個地址里面到底有什么: 這里寫圖片描述 我們可以看到_bb上面的這個地址里面存了一個十六進制數字14,_cc上面的地址里面存了一個十六進制的數字0c,這是什么呢,這其實是d中包含的BB、CC類型各自的地址到_a地址的偏移量,請看以下代碼: DD* pd = new DD; BB* pb = pd; 繼承有復制兼容性規則,而虛繼承也要滿足這個規則,如果沒有這兩個指針,上述代碼運行時_aa與_bb,不在一起,這里也就無法截斷賦值,賦值兼容性規則就不滿足了,而有了這兩個指針,我們這樣賦值時,通過這兩個指針找到了偏移量,加上偏移量就可以訪問到_aa,也就滿足了復制兼容性規則。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 保定市| 双鸭山市| 成安县| 酉阳| 武山县| 兴山县| 江都市| 都匀市| 同德县| 岳普湖县| 涡阳县| 永川市| 通道| 封丘县| 来凤县| 旬阳县| 伊金霍洛旗| 黔南| 高陵县| 南昌市| 昌吉市| 无锡市| 行唐县| 彰化市| 莒南县| 封丘县| 田林县| 库车县| 双江| 阳城县| 大洼县| 金寨县| 鲁山县| 夹江县| 南川市| 多伦县| 田阳县| 新宾| 禄劝| 讷河市| 湖南省|