可以在不重新编译客户端代码的情况下扩展虚拟接口吗?

Can one extend virtual interface without recompilation of client code?

本文关键字:情况下 代码 扩展 虚拟 接口 客户端 新编译 编译      更新时间:2023-10-16

标准库为类提供了虚函数。这个类可以用新的虚函数扩展而不需要重新编译动态链接到库的二进制文件吗?

我认为这在标准中是不可能的。有平台允许这样做吗?

如果新函数只添加到类体的末尾,会更容易吗?

该标准与二进制兼容性无关。它关注的是类,通过将类的定义从一个翻译单元"更改"到另一个翻译单元,您确实调用了未定义的行为。

大多数编译器允许在不需要重新编译的情况下进行一些更改,但是列表很小…对于这个,我想说这可能是不可能的,取决于派生类的先验知识。

我预见到的问题在于编译器通常在虚拟表上执行的优化。

创建带有虚函数的类时,得到的虚表如下所示:

// B virtual table
0 - Offset to complete object
1 - RTTI
2 - func0
3 - func1
...

为了获得一些空间,派生类自己的虚函数通常被"追加":

// D virtual table
Same as B
N+3 - func(N+1)
N+4 - func(N+2)

这样,D对象只有一个虚指针,即使类型(静态地)是B(通过指针或引用),也可以这样使用。

然而,如果你要扩展B而不重新编译D,那么它只会崩溃,因为当调用BN+1函数时,你会调用DN+1函数,这可能甚至没有相同的参数…牛津大学出版社!

如果知道,那么派生类就不会添加自己的虚函数。

相关文章: