库提供具有虚函数的类。可以用新的虚函数扩展这个类而不重新编译动态链接到库的二进制文件吗?
我相信这在标准中是不可能的。有平台允许吗?
如果只将新函数添加到类体的末尾,那会更容易吗?
库提供具有虚函数的类。可以用新的虚函数扩展这个类而不重新编译动态链接到库的二进制文件吗?
我相信这在标准中是不可能的。有平台允许吗?
如果只将新函数添加到类体的末尾,那会更容易吗?
该标准不关心二进制兼容性。尽管它与类有关,并且通过将类的定义从一个翻译单元“更改”到另一个翻译单元,您确实会调用未定义的行为。
大多数编译器确实允许在不需要重新编译的情况下进行一些更改,但是列表很小……对于这个我想说这可能是不可能的,这取决于派生类的先验知识。
我预见的问题在于编译器通常对虚拟表进行的优化。
当你用虚函数创建一个类时,你会得到一个如下所示的虚表:
// 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
对象只有一个虚拟指针,即使类型是(静态)a B
(通过指针或引用)也可以这样使用。
但是,如果您要在B
不重新编译的情况下进行扩展D
,那么它只会崩溃,因为在调用您的N+1
函数时,您B
会改为调用可能甚至没有相同参数的函数......哎呀!N+1
D
但是,如果您知道没有派生类添加任何自己的虚函数,则可以这样做。