假设我有一个类B_Impl
,它继承并实现了一个纯抽象类B
(不包含任何数据字段(。
假设类A
仅通过B*
使用B_Impl
。
如果我在B_Impl.h
中添加一个字段(很明显,A
中没有包含(,ABI的兼容性会被保留吗?
我想,它不会被保存下来,——看完之后https://wiki.qt.io/D-Pointer.
但我可以在我的应用程序中看到,在更改B_Impl.h
之后,类A
的对象文件被而不是重新生成,并且一切仍然很好。
也许,这是因为在我的应用程序中,A
和B
是同一应用程序的一部分,而B
不是A
调用的库?还是因为vtable
总是被定位为存储器中的第一个字段,并且将另一个字段添加到B_Impl.h
(其"在"B
之下(不会改变vtable
是第一个字段的事实?或者这个东西是通过链接器而不是通过重新生成A
对象文件来纠正的?
老实说,我有点困惑:
-
这个ABI问题只与库有关吗?
-
当我调用
B*
并通过更改B_Impl.h
(即忽略文章中建议的Pimpl原则(而不重新生成A
-对象文件来获得一些seg错误时,我如何调整我的应用程序中的情况(其中A使用B而不是库(? -
或者,如果我通过接口
B*
使用一个类,我可以通过添加新字段等尽可能多地更改它的B_Impl.h
,而不用担心我将不得不在同一应用程序中重新编译直接使用B
的A
,或者重新编译使用B
作为共享库调用的C
,这是真的吗?感谢您的关注!
如果我向B_Impl.h添加一个字段(显然,不包括在a中(,ABI的兼容性会被保留吗?
是。如果翻译单元不包括B_Impl
的定义,那么对B_Impl
的更改不会影响兼容性。
接口兼容性——无论是API还是ABI——只有在使用接口时才重要。在您的示例中,使用了B
的接口;而不是CCD_ 31的接口。
这个ABI问题只与库有关吗?
B_Impl
是否在库中应该无关紧要。