库提供了一个具有虚函数的类。可以使用新的虚函数扩展此类,而无需重新编译动态链接到库的二进制文件吗?
我相信这在标准中是不可能的。有平台允许吗?
如果只将新函数添加到类主体的末尾会更容易吗?
答案 0 :(得分:5)
该标准不涉及二进制兼容性。它关注的是类,并且通过将类的定义从一个翻译单元“改变”到另一个翻译单元,你确实会调用未定义的行为。
大多数编译器都允许进行大量更改而无需重新编译,但是列表很小......对于这个,我会说这可能是不可能的,取决于先验知识。派生类。
我预见到的问题在于编译器通常在虚拟表上执行的优化。
使用虚函数创建类时,会得到一个如下所示的虚拟表:
// 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
,那么它就会崩溃,因为在调用N+1
的{{1}}函数时你会调用它B
的{{1}}函数甚至可能没有相同的参数... oups!
但是,如果你知道而不是派生类添加任何自己的虚函数,那么可以这样做。