2013-06-26 116 views
17

我想了解繼承順序在C++中的影響..我在網上查找,但我找不到明確而充分的答案...C++多重繼承順序

因此,爲了的問題,假設有2類:B類和C類。

現在,定義:

class A1 : public B, public C{ ... }; 
class A2 : public C, public B{ ... }; 

是什麼A1和A2之間的差異?

非常感謝!

+0

Intersting問題。我想知道答案。我發現這個鏈接 - http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm,它聲稱,「推導的順序僅與確定構造函數的默認初始化順序和通過析構函數清理的順序有關。「也許有人可以證實這一點? – OldProgrammer

回答

11

推導順序僅與確定構造函數的默認初始化順序和通過析構函數清理有關。

除了由構造函數(12.6.2),清理(12.4)和存儲佈局(9.2,11.1)進行初始化的語義指定外,派生順序並不重要。 - 注完]」(§10.1/ 2)

從IBM的C++文檔:Multiple inheritance

+1

如果您直接放置報價而不是鏈接,則您的答案會更好。 –

+1

報價是直接存在嗎?或者我錯過了什麼? – Haagenti

+0

確實如此,但原始鏈接很俗氣:/ –

7

的C++ 11標準說(§10.1):

推導的順序是不顯著除非由構造(12.6.2),清理(12.4), 和存儲佈局(9.2,11.1)中指定由初始化 語義。

個三個引用段落顯示,

  • 構造函數的調用你寫下來(列表中的第一個基類構造第一)(§12.6.2.10)的順序。不同的規則適用於在任何直接基類之前總是由派生最多的類構造的虛擬基類。
  • 破壞程序按構造的反向順序調用(列表中的第一個基類最後被破壞)
  • 存儲佈局未指定。你不能對內存中的類佈局做任何假設。唯一的例外是所謂的標準佈局類(§9),它基本上是C風格的結構。但是由於這些類不允許在類層次結構中擁有多個非靜態成員的類,所以這個問題在這裏並不適用。

請注意,內存佈局可能很重要。例如,如果一個外部庫做出天真的C風格轉換,假設它感興趣的對象的部分在開頭,它可能會導致難以調試的運行時錯誤。

+3

我不「考慮」任何東西。 「定義的實現」是在C89 ANSI標準中定義的,並且在C++中使用了相同的定義。只有標準描述爲「實現定義」的東西才被認爲是「實現定義的」:**如果某些東西是「實現定義的」,那麼需要實現來記錄它。這個實現當然也允許記錄任何想要的東西。它可以描述'operator +'參數的評估順序,但這不是必需的。它可以記錄vtable的佈局,但這不是必需的。 – curiousguy

+0

「_it是實現者確定layout_的責任」每次你寫'f(g(),h())'時,實現也必須從兩種可能性中選擇一種評估順序,但它選擇的方式很少描述。該實現負責許多除源代碼外沒有記錄的內容。 – curiousguy

+0

@curiousguy答案正是想要表達的是:_你不能對班級佈局做任何假設。術語_implementation-defined_在ISO語言和口語語言中有着稍微不同的含義(這是標準中使用的許多術語的情況)。爲了避免這種混淆,我改變了答案的措詞。如果您的原始帖子已經包含您倒數第二的信息,我們可以在更少的帖子中完成此操作。謝謝你和我在一起。 – ComicSansMS