2011-09-13 35 views
3

即使在派生類中進行涉及虛擬的其他更改,類視圖的ABI是否仍然保持穩定?接口(抽象類)與其他虛擬更改的ABI兼容

也就是說,我有一個接口InterfaceA(具有許多純虛函數的抽象類)和一個繼承自它的類DerivedB。我寫了一個函數庫,它的功能是InterfaceA *。我想知道的是,只要接口本身沒有改變,接口是否保持二進制兼容。

清除,如果我修改InterfaceA我不認爲代碼是二進制兼容的。但是,如果我只是修改DerivedB,說我繼承更多接口或添加其他虛擬功能。在最極端的說法中,我從另一個定義InterfaceA的類繼承了多個繼承。儘管所有這些變化,InterfaceA仍然保持二進制兼容?

我的假設和經驗到現在是,它是兼容的。我只是尋找這個確認(或反駁,如果不兼容)。

注意:我不關心動態打字或其他投射,我只關心界面功能本身。

另請注意:假設正在使用的編譯器版本是ABI穩定的整體 - 沒有主要的版本更改。

+2

可能[this](http://accu.org/index.php/journals/1718)這篇文章對你很有意思。 – Simon

回答

3

是的,只要InterfaceA中虛擬函數的名稱,參數和順序沒有改變,它就會保持二進制兼容。請注意,這允許您在類聲明的末尾添加函數。

(這有可能是不明確的C++規範保證,但COM依賴於這個如此大的C++編譯器會以這種方式工作。)

+0

我認爲你對規範是正確的:它對ABI甚至圖書館都很沉默。我正在使用GCC。如果一個重載的虛擬函數(同名)被添加到接口的末尾會怎麼樣? –

+0

這不應該破壞二進制兼容性。 –

+0

根據這裏的答案:http://stackoverflow.com/questions/14875052/pure-virtual-functions-and-binary-compatibility,在接口的末尾添加虛擬功能將無法在MSVC上工作。 – Eugene

0

你不跨越ABI邊界使用DerivedB假設,你應該可以做任何你想做的事情。純虛擬類(DerivedA)是最重要的,如果你不改變它,那麼你是正確的 - 任何使用指向InterfaceA的指針都不會有任何跨越邊界的問題。

事實上,你甚至可以在InterfaceA的結尾添加一個函數,只要它是一個葉子接口(即沒有其他接口繼承它),並且該函數不是另一個函數的重載。當然,它需要遵循與其他函數相同的「ABI規則」 - 即參數類型必須是原始類型或指向其他接口的指針等。如果您有版本控制系統,您的應用程序可以檢查插件的版本並確定是否或者不能安全地調用新函數 - 從而爲新插件添加功能,但在更改之前編譯的舊插件仍然可以工作。很酷!