可以在不重新编译客户端代码的情况下扩展虚拟接口吗?
Can one extend virtual interface without recompilation of client code?
标准库为类提供了虚函数。这个类可以用新的虚函数扩展而不需要重新编译动态链接到库的二进制文件吗?
我认为这在标准中是不可能的。有平台允许这样做吗?
如果新函数只添加到类体的末尾,会更容易吗?
该标准与二进制兼容性无关。它关注的是类,通过将类的定义从一个翻译单元"更改"到另一个翻译单元,您确实调用了未定义的行为。
大多数编译器允许在不需要重新编译的情况下进行一些更改,但是列表很小…对于这个,我想说这可能是不可能的,取决于派生类的先验知识。
我预见到的问题在于编译器通常在虚拟表上执行的优化。
创建带有虚函数的类时,得到的虚表如下所示:
// 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
,那么它只会崩溃,因为当调用B
的N+1
函数时,你会调用D
的N+1
函数,这可能甚至没有相同的参数…牛津大学出版社!
如果知道,那么派生类就不会添加自己的虚函数。
相关文章:
- 这个c++代码是如何在没有定义函数的情况下运行的
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 在什么情况下,我想在 C/C++ 代码中使用内联汇编代码
- 可以在没有构建代码的情况下转到定义吗?
- 在没有引用传递资源的情况下,如何在java中简化这些代码
- 尝试在不使用转换概念的情况下呈现此代码
- 寻找有关为什么此C++代码在没有引用的情况下不起作用的解释
- 在运行时,何时完全初始化 std 库才能在不破坏代码的情况下使用它?
- 在存在错误代码的情况下输出参数与 NRVO
- 在给定相同的输入的情况下,某些代码怎么可能花费更多时间来运行,这似乎只是因为它处于循环中?
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 为什么我的代码在没有 chroot 函数的情况下工作,但使用 chroot 函数失败?
- 如何在不复制此代码的情况下将多个函数放入多个命名空间?
- 如何在 C++03 中没有重复代码的情况下在堆栈上创建一个非常量 C 字符串数组?
- 在没有额外代码的情况下链接两个独立类的最通用方法是什么?
- 如何在没有性能命中的情况下抽象SIMD代码来处理不同的数据类型
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- 打包结构,而不是在没有代码重复的情况下打包
- 如何在不中断剩余代码的情况下仅C++中输入整数
- 如何在<typename> <long> 不更改给定代码的情况下将自定义向量与 STL 向量相互转换?