即使在派生类中进行了涉及虚拟的其他更改,类的视图的ABI是否仍然保持稳定?
也就是说,我有一个接口InterfaceA
(具有许多纯虚函数的抽象类)和一个继承自它的类DerivedB
。我写了一个函数采用InterfaceA *
的库。我想知道的是,只要接口本身没有改变,接口是否仍然是二进制兼容的。
清除,如果我修改InterfaceA
我不希望代码是二进制兼容的。但是,如果我只修改DerivedB
,我会继承更多接口或添加其他虚拟功能。最极端的说法是我从另一个定义InterfaceA
的类中继承。尽管进行了所有这些更改,InterfaceA
仍保持二进制兼容吗?
我的假设和经验到现在是,它是兼容的。我只是想要确认这一点(如果不相容则反驳)。
注意:我不关心动态类型或其他转换,我只关心接口函数本身。
另请注意:假设正在使用的编译器版本是完整的ABI稳定版本 - 没有主要版本更改。
答案 0 :(得分:3)
是的,只要InterfaceA中的虚函数的名称,参数和顺序没有改变,它就会保持二进制兼容。请注意,这允许您在类声明的末尾添加函数。
(C ++规范可能没有明确保证这一点,但COM依赖于此,因此大型C ++编译器将以这种方式工作。)
答案 1 :(得分:0)
假设你没有在ABI边界使用DerivedB,你应该可以做任何你想做的事情。纯虚拟类(DerivedA)是最重要的,如果你不改变它,那么你就是正确的 - 任何使用指向InterfaceA的指针都不会有任何跨越边界的问题。
实际上,您甚至可以在InterfaceA的末尾添加一个函数,只要它是一个叶子接口(即没有其他接口继承它),并且该函数不是另一个函数的重载。当然,它需要遵循相同的" ABI规则"作为您的其他功能 - 即参数类型必须是基本类型或指向其他接口的指针等。如果您有版本控制系统,您的应用程序可以检查插件的版本并确定新功能是否可以安全调用 - 因此为更新的插件添加功能,但在更改之前编译的旧插件仍然有效。非常酷!