亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

深入解析C++編程中基類與基類的繼承的相關知識

2020-05-23 14:09:31
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++編程中基類與基類的繼承的相關知識,包括多個基類繼承與虛擬基類等重要知識,需要的朋友可以參考下
 

基類
繼承過程將創建一個新的派生類,它由基類的成員加上派生類添加的任何新成員組成。在多重繼承中,可以構建一個繼承關系圖,其中相同的基類是多個派生類的一部分。下圖顯示了此類關系圖。

深入解析C++編程中基類與基類的繼承的相關知識

單個基類的多個實例
在該圖中,顯示了 CollectibleString 和 CollectibleSortable 的組件的圖形化表示形式。但是,基類 Collectible 位于通過 CollectibleSortableString 路徑和 CollectibleString 路徑的 CollectibleSortable 中。若要消除此冗余,可以在繼承此類類時將其聲明為虛擬基類。

多個基類
如多重繼承中所述,類可以從多個基類派生。在多重繼承模型中(其中,類派生自多個基類),使用 base-list 語法元素指定基類(請參閱概述中的“語法”一節)。例如,可以指定派生自 CollectionOfBook 和 Collection 的 Book 的類聲明:

// deriv_MultipleBaseClasses.cpp// compile with: /LDclass Collection {};class Book {};class CollectionOfBook : public Book, public Collection { // New members};

指定基類的順序并不重要,只不過在某些情況下,將調用構造函數和析構函數。在這些情況下,指定基類的順序將影響:
構造函數進行初始化的順序。如果您的代碼依賴要在 Book 部分之前初始化的 CollectionOfBook 的 Collection 部分,則規范的順序很重要。按照 base-list 中指定類的順序執行初始化。
調用析構函數以進行清理的順序。同樣,如果在銷毀另一部分時必須呈現類的特定“部分”,則順序非常重要。按照與 base-list 中指定類的順序相反的順序調用析構函數。
注意
基類的規范順序會影響類的內存布局。不要基于內存中基成員的順序做出任何編程決策。
當指定 base-list 時,不能多次指定同一類名。但是,可以將類多次作為派生類的間接基。

 

虛擬基類
由于一個類可能多次成為派生類的間接基類,因此 C++ 提供了一種優化這種基類的工作方式的方法。虛擬基類提供了一種節省空間和避免使用多重繼承的類層次結構中出現多義性的方法。
每個非虛擬對象包含在基類中定義的數據成員的一個副本。這種重復浪費了空間,并要求您在每次訪問基類成員時都必須指定所需的基類成員的副本。
當將某個基類指定為虛擬基時,該基類可以多次作為間接基而無需復制其數據成員?;惖臄祿蓡T的單個副本由將其用作虛擬基的所有基類共享。
當聲明虛擬基類時,virtual 關鍵字將顯示在派生類的基列表中。
請考慮下圖中的類層次結構,它演示了模擬的午餐排隊。

深入解析C++編程中基類與基類的繼承的相關知識

模擬午餐排隊圖
在該圖中,Queue 是 CashierQueue 和 LunchQueue 的基類。但是,當將這兩個類組合成 LunchCashierQueue 時,會出現以下問題:新類包含類型 Queue 的兩個子對象,一個來自 CashierQueue,另一個來自 LunchQueue。下圖顯示了概念上的內存布局(實際物理內存布局可能會進行優化)。

深入解析C++編程中基類與基類的繼承的相關知識

模擬午餐排隊對象
請注意,Queue 對象中有兩個 LunchCashierQueue 子對象。以下代碼將 Queue 聲明為虛擬基類:

// deriv_VirtualBaseClasses.cpp// compile with: /LDclass Queue {};class CashierQueue : virtual public Queue {};class LunchQueue : virtual public Queue {};class LunchCashierQueue : public LunchQueue, public CashierQueue {};

virtual 關鍵字可確保只包含子對象 Queue 的一個副本(請參閱下圖)。

深入解析C++編程中基類與基類的繼承的相關知識

使用虛擬基類模擬午餐排隊對象
一個類可以同時具有一個給定類型的虛擬組件和非虛擬組件。下圖演示了這種情況。

深入解析C++編程中基類與基類的繼承的相關知識

同一個類的虛擬組件與非虛擬組件
在圖中,CashierQueue 和 LunchQueue 將 Queue 用作虛擬基類。但是,TakeoutQueue 將 Queue 指定為基類而不是虛擬基類。因此,LunchTakeoutCashierQueue 具有類型 Queue 的兩個子對象:一個來自包含 LunchCashierQueue 的繼承路徑,另一個來自包含 TakeoutQueue 的路徑。下圖對此進行了演示。

深入解析C++編程中基類與基類的繼承的相關知識

帶虛擬和非虛擬繼承的對象布局
注意
與非虛擬繼承相比較,虛擬繼承提供了顯著的大小優勢。但是,它可能會引入額外的處理開銷。
如果派生類重寫它從虛擬基類繼承的虛函數,并且派生基類的構造函數或析構函數使用指向虛擬基類的指針調用該虛函數,則編譯器可能會將其他隱藏的“vtordisp”字段引入到具有虛擬基的類中。/vd0 編譯器選項將禁止添加隱藏的 vtordisp 構造函數/析構函數置換成員。默認的 /vd1 編譯器選項會在必要時啟用它們。僅當確定所有類構造函數和析構函數以虛擬方式調用虛函數時才關閉 vtordisps。
/vd 編譯器選項會影響整個編譯模塊。使用 vtordisp 雜注可以逐個類地禁用 vtordisp 字段,然后重新啟用這些字段:

#pragma vtordisp( off )class GetReal : virtual public { ... };#pragma vtordisp( on )

對于前面的類聲明,如下所示的代碼是不明確的,因為 b 所指的 b 是在 A 中還是在 B 中并不清楚:

C *pc = new C;pc->b();

名稱多義性
多重繼承使得沿多個路徑繼承名稱成為可能。沿這些路徑的類成員名稱不一定是唯一的。這些名稱沖突稱為“多義性”。
任何引用類成員的表達式必須采用明確的引用。以下示例說明如何產生多義性:

// deriv_NameAmbiguities.cpp// compile with: /LD// Declare two base classes, A and B.class A {public: unsigned a; unsigned b();};class B {public: unsigned a(); // Note that class A also has a member "a" int b();  // and a member "b". char c;};// Define class C as derived from A and B.class C : public A, public B {};

請看前面的示例。由于名稱 a 是類 A 和類 B 的成員,因此編譯器無法辯明哪個 a 指定將調用函數。如果成員可以引用多個函數、對象、類型或枚舉數,則對該成員的訪問是不明確的。
編譯器通過按此順序執行測試來檢測多義性:
如果對名稱的訪問是不明確的(如上所述),則會生成錯誤消息。
如果重載函數是明確的,則將解析它們。(有關函數重載多義性的詳細信息,請參閱參數匹配。)
如果對名稱的訪問違背了成員訪問權限,則會生成錯誤消息。(有關詳細信息,請參閱成員訪問控制。)
在表達式通過繼承產生多義性時,您可以通過限定考慮中的名稱及其類名來手動消除該多義性。若要適當編譯上面的示例而不產生多義性,請使用如下代碼:

C *pc = new C;pc->B::a();

注意
在聲明 C 時,如果在 B 的范圍內引用 C,則可能會導致出現錯誤。但不會發出任何錯誤,直到在 B 的范圍內實際創建對 C 的非限定引用。
主導
通過一個繼承關系圖到達多個名稱(函數、對象或枚舉器)是可能的。這種情況被視為與非虛擬基類一起使用時目的不明確。這些名稱與虛擬基類一起使用時目的不明確,除非其中一個名稱“決定”其他名稱。
如果某個名稱在兩個類中定義并且一個類派生自另一個類,則該名稱可控制另一個名稱。基準名稱是派生類中的名稱;此名稱在本應出現多義性時使用,如以下示例所示:

// deriv_Dominance.cpp// compile with: /LDclass A {public: int a;};class B : public virtual A {public: int a();};class C : public virtual A {};class D : public B, public C {public: D() { a(); } // Not ambiguous. B::a() dominates A::a.};

不明確的轉換
從指向類類型的指針或對類類型的引用的顯式或隱式轉換可能會導致多義性。下圖(指向基類的指針的不明確轉換)顯示如下內容:
D 類型的對象的聲明。
將 address-of 運算符 (&) 應用于該對象的效果。請注意,address-of 運算符總是提供該對象的基址。
將使用 address-of 運算符獲取的指針顯式轉換為基類類型 A 的效果。請注意,將該對象的地址強制轉換為 A* 類型并不總是為編譯器提供足夠的信息,以供 A 類型的子對象進行選擇;在這種情況下,將存在兩個子對象。

深入解析C++編程中基類與基類的繼承的相關知識

指針到基類的不明確轉換
到類型 A*(指向 A 的指針)的轉換是不明確的,因為無法辯明 A 類型的哪個子對象是正確的。請注意,您可以通過顯式指定要使用的子對象來避免多義性,如下所示:

(A *)(B *)&d  // Use B subobject.(A *)(C *)&d  // Use C subobject.

多義性和虛擬基類
如果使用虛擬基類,則函數、對象、類型和枚舉數可通過多重繼承路徑到達。因為僅有一個基類實例,因此在訪問這些名稱時不存在二義性。
下圖顯示如何使用虛擬和非虛擬繼承構成對象。

深入解析C++編程中基類與基類的繼承的相關知識

虛擬和非虛擬派生
在該圖中,通過非虛擬基類訪問類 A 的任何成員都將導致二義性;編譯器沒有解釋是使用與 B 關聯的子對象還是與 C 關聯的子對象的信息。但是,將 A 指定為虛擬基類時,訪問哪一個子對象都不成問題。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内精品久久久久久久久| 国产丝袜一区二区三区| 国内精品模特av私拍在线观看| 国产视频精品xxxx| 久色乳综合思思在线视频| 色噜噜国产精品视频一区二区| 久久九九亚洲综合| 国产精品美女无圣光视频| 欧美激情欧美狂野欧美精品| 深夜福利国产精品| 国产91精品青草社区| 欧美性色19p| 久久精品视频在线播放| 91精品国产综合久久男男| 欧美精品免费看| 精品香蕉一区二区三区| 韩国美女主播一区| 91精品国产99久久久久久| 久久久久久久久久国产精品| 91久久国产精品91久久性色| 精品综合久久久久久97| 欧美国产第二页| 欧美成人午夜激情在线| 亚洲国产精彩中文乱码av| 久久免费视频网站| 国产香蕉精品视频一区二区三区| 久热精品视频在线免费观看| 国产亚洲精品久久久优势| 亚洲精品福利资源站| 日韩视频免费看| 午夜精品一区二区三区在线播放| 亚洲在线一区二区| 久久久精品视频成人| 欧美在线欧美在线| 国内精品一区二区三区四区| 欧美亚洲国产另类| 日韩成人在线免费观看| 亚洲免费影视第一页| 欧美午夜精品伦理| 亚洲一区二区三区视频播放| 国产精品视频不卡| 国产精品国产三级国产aⅴ9色| 久久久久久久久久久久久久久久久久av| 欧美国产日本高清在线| 国产日韩欧美在线播放| 成人h片在线播放免费网站| 国产免费亚洲高清| www.午夜精品| 成人激情视频网| 欧美在线精品免播放器视频| 日产日韩在线亚洲欧美| 亚洲在线视频观看| 色综合视频一区中文字幕| 亚洲图片欧美日产| 国产成人精品日本亚洲专区61| 久久精品视频中文字幕| 欧美大片大片在线播放| xxxx欧美18另类的高清| 欧美夫妻性视频| 亚洲视频欧美视频| 欧美成在线视频| 亚洲天堂av网| 亚洲成人动漫在线播放| 欧美在线视频播放| 国产精品美女在线观看| 在线播放国产精品| 亚洲黄色www网站| 黑人欧美xxxx| 国产成人在线一区| 日韩黄色在线免费观看| 色综合久综合久久综合久鬼88| 欧美成人精品激情在线观看| 日韩精品视频免费| 亚洲综合最新在线| 日韩欧美亚洲国产一区| 亚洲影院高清在线| 在线视频亚洲欧美| 国产精品一区二区av影院萌芽| 欧美成人合集magnet| 亚洲高清福利视频| 欧洲亚洲妇女av| 欧美成人精品h版在线观看| 一区二区三区回区在观看免费视频| 亚洲free性xxxx护士白浆| 日韩在线观看免费高清完整版| 91欧美精品成人综合在线观看| 亚洲美女免费精品视频在线观看| 国产午夜精品理论片a级探花| 亚洲精品资源在线| 国产91久久婷婷一区二区| 国产精品香蕉av| 亚洲男人第一av网站| 深夜福利国产精品| 91精品视频免费看| 91中文在线观看| 性欧美xxxx视频在线观看| 国产丝袜高跟一区| 久久精品人人做人人爽| 亚洲国产精品美女| 狠狠躁天天躁日日躁欧美| 欧美日韩亚洲系列| 日韩第一页在线| 91深夜福利视频| 亚洲尤物视频网| 亚洲最大中文字幕| 欧美激情精品久久久久久| 亚洲淫片在线视频| 国产精品视频午夜| 国产精品久久久久久久久久久久久久| 国产精品a久久久久久| 国产z一区二区三区| 亚洲美女免费精品视频在线观看| 日韩av一区二区在线| 亚洲aⅴ日韩av电影在线观看| 一区二区三欧美| 亚洲日韩中文字幕| 成人免费xxxxx在线观看| 国产第一区电影| 国产成人精品在线观看| 日日摸夜夜添一区| 国产精品久久久久久五月尺| 欧美日本精品在线| 伊人久久久久久久久久| 亚洲天堂av在线免费| 久久夜色精品亚洲噜噜国产mv| 国产精品国产三级国产aⅴ浪潮| 日本亚洲欧美三级| 中文字幕亚洲无线码在线一区| 成人羞羞国产免费| 成人春色激情网| 精品福利在线视频| 国产亚洲欧美日韩精品| 成人做爽爽免费视频| 亚洲日韩第一页| 日韩精品在线免费观看视频| 国产精品吹潮在线观看| 欧美日韩国产综合新一区| 亚洲区免费影片| 日韩中文字幕在线| 久久中文精品视频| 欧美电影电视剧在线观看| 91精品在线国产| 日韩av免费在线| 国产欧美日韩中文字幕| 全色精品综合影院| 欧美亚洲视频一区二区| 国产精品视频999| 久久伊人色综合| 久久精品久久精品亚洲人| 亚洲小视频在线| 亚洲视频在线免费观看| 国产成人精品综合| 亚洲福利视频专区| 亚洲天堂久久av| 国产精品视频成人| 亚洲国产91色在线| 久久视频国产精品免费视频在线| 国产亚洲美女久久| 国产91露脸中文字幕在线| xxxx欧美18另类的高清| 国产91久久婷婷一区二区| 国产精品青青在线观看爽香蕉| 91大神在线播放精品| 久久成年人视频|