C++使用抽象类无需 pimpl 即可实现 abi 兼容性

发布于 2025-01-14 18:26:01 字数 1215 浏览 6 评论 0原文

假设我有一个类 B_Impl ,它继承并实现了一个纯抽象类 B (不包含任何数据字段)。

假设类 A 仅通过 B* 使用 B_Impl

如果我向 B_Impl.h 添加一个字段(显然,A 中未包含该字段),是否会保留 ABI 兼容性?

我想,它不会被保留,--阅读 https://wiki.qt.io/ 后D 指针

但我可以在我的应用程序中看到,更改 B_Impl.h 后,A 类的目标文件不会重新生成,并且一切仍然正常工作。

也许,这是因为在我的应用程序中 AB 是同一个应用程序的一部分,而 B 不是 A 调用的库?或者是因为 vtable 始终位于内存中的第一个字段,并向 B_Impl.h 添加另一个字段(位于“B”之下) code>) 不会改变 vtable 是第一个字段的事实吗?或者这个东西是由链接器以某种方式纠正的,而不是通过重新生成 A-object-file 来纠正的?

老实说,我在这里有点困惑:

  • 这个 ABI 问题仅与库有关吗?

  • 当我调用 B* 并通过更改 B_Impl.h 获得一些段错误时,如何调整应用程序中的情况(其中 A 使用 B 不作为库) code>,(即忽略文章中建议的 Pimpl 原则),并且不重新生成 A-object-file?

  • 或者,如果我通过接口 B* 使用一个类,我可以通过添加新字段等来尽可能多地更改它的 B_Impl.h ,并且不用担心我必须直接在同一个应用程序中重新编译使用 BA 或重新编译使用 C >B 作为对共享库的调用?感谢您的关注!

Suppose I have a class B_Impl which inherits and implements a pure abstract class B (not containing any data-fields).

Suppose class A uses B_Impl via B* only.

If I add a field to B_Impl.h (clearly, not included by A), will ABI compatability be preserved?

I thought, that it will not be preserved, -- after reading https://wiki.qt.io/D-Pointer.

But I can see in my app that after changing B_Impl.h, the object file for class A is not regenerated and everything still works great.

Maybe, this is because in my app A and B are part of the same app and B is not a library called by A? Or is it because vtable is located as the very first field in the memory always and adding another field to B_Impl.h (which is "beneath" B) does not change the fact that vtable is the first field? Or is this stuff somehow corrected by the linker rather than by re-generating A-object-file?

Honestly, I am a bit confused here:

  • Is this ABI problem is only about libraries?

  • How can I modulate the situation in my app (where A uses B not as a library) when I call B* and get some seg-fault by changing B_Impl.h, (i.e. by ignoring the Pimpl principle, suggested in the article), and not re-generating A-object-file?

  • Or is it true that if I use a class via interface B* I can change its B_Impl.h as much as I could by adding new fields etc. and not being afraid that I will have to re-compile A that uses B directly in the same app or re-compile C that uses B as a call to a shared library? Thank you for attention!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

治碍 2025-01-21 18:26:01

如果我向 B_Impl.h 添加一个字段(显然,A 不包含该字段),ABI 兼容性会保留吗?

是的。如果翻译单元不包含 B_Impl 的定义,则对 B_Impl 的更改不会影响兼容性。

接口兼容性 - 无论是 API 还是 ABI - 仅在使用接口时才重要。在您的示例中,使用了 B 的接口;不是B_Impl的接口。

这个 ABI 问题仅与库有关吗?

B_Impl 是否在库中并不重要。

If I add a field to B_Impl.h (clearly, not included by A), will ABI compatability be preserved?

Yes. If a translation unit doesn't include the definition of B_Impl, then changes to B_Impl won't affect the compatibility.

The interface compatibility - whether it is API or ABI - matters only when the interface is used. In your example, the interface of B is used; not the interface of B_Impl.

Is this ABI problem is only about libraries?

Whether B_Impl is in a library or not shouldn't matter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文