3

即使在派生类中进行了涉及虚拟的其他更改,类视图的 ABI 是否保持稳定?

也就是说,假设我有一个接口InterfaceA(具有许多纯虚函数的抽象类)和一个DerivedB从它继承的类。我编写了一个库,该库具有采用InterfaceA *. 我想知道的是,只要接口本身不改变,接口是否保持二进制兼容。

清楚,如果我修改InterfaceA我不希望代码是二进制兼容的。但是,如果我只是修改DerivedB,比如说我继承更多接口或添加其他虚拟功能。在最极端的情况下,我从另一个定义InterfaceA. 尽管有所有这些变化,是否InterfaceA仍保持二进制兼容?

到目前为止,我的假设和经验是,是的,它是兼容的。我只是在寻找对此的确认(如果不兼容,则进行反驳)。

注意:我不关心动态类型或其他类型转换,我只关心接口函数本身。

另请注意:假设正在使用的编译器版本整体上是 ABI 稳定的——没有主要版本更改。

4

2 回答 2

3

是的,只要 InterfaceA 中虚函数的名称、参数和顺序不变,它将保持二进制兼容。请注意,这允许您在类声明的末尾添加函数。

(C++ 规范可能没有明确保证这一点,但 COM 依赖于此,因此大型 C++ 编译器将以这种方式工作。)

于 2011-09-13T08:40:48.057 回答
0

假设您没有跨 ABI 边界使用 DerivedB,您应该能够做任何您想做的事情。纯虚拟类 (DerivedA) 是最重要的,如果您不更改它,那么您是正确的 - 任何使用指向 InterfaceA 的指针的东西都不会遇到任何问题。

事实上,您甚至可以在 InterfaceA 的末尾添加一个函数,只要它是叶接口(即没有其他接口继承自它)并且该函数不是另一个函数的重载。当然,它需要遵循与您的其他函数相同的“ABI 规则”——即参数类型必须是原始类型或指向其他接口的指针等。如果您有版本控制系统,您的应用可以检查插件的版本并确定是否或者不能安全地调用新函数 - 因此为较新的插件添加功能,但在更改之前编译的旧插件仍然可以工作。很酷!

于 2014-12-17T23:30:25.700 回答