是否可以在不重新编译客户端代码的情况下扩展虚拟接口?
库提供具有虚函数的类。可以使用新的虚拟函数扩展此类,而无需重新编译动态链接到库的二进制文件吗?
我相信这在标准中是不可能的。有平台允许这样做吗?
如果仅将新函数添加到类主体的末尾,会更容易吗?
A library provides a class with virtual functions. Can this class be extended with new virtual functions without recompiling binaries dynamically linked to the library?
I beleive this is not possible in standard. Are there platforms allowing this?
Would that be easier if new functions are only added to the end of the class body?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该标准不关心二进制兼容性。它与类有关,并且通过将类的定义从一个翻译单元“更改”为另一个翻译单元,您确实会调用未定义的行为。
大多数编译器确实允许进行大量更改而无需重新编译,但是列表很小......对于这个,我想说这可能是不可能的,取决于派生类的先验知识< /em>.
我预见的问题在于编译器通常对虚拟表进行的优化。
当你创建一个带有虚函数的类时,你会得到一个如下所示的虚表:
为了获得一些空间,派生类自己的虚函数通常被“附加”:
这样一个
D
对象只有一个虚拟指针,即使类型(静态)为B
(通过指针或引用)也可以这样使用。但是,如果您要扩展
B
而不重新编译D
,那么它只会崩溃,因为在调用N+1
函数时code>B 你会调用D
的N+1
函数,它甚至可能没有相同的参数......哎呀!不过,如果您知道没有派生类添加其自己的任何虚函数,那么这是可以完成的。
The standard is not concerned with binary compatibility. It is concerned though with classes, and by "changing" the definition of a class from one translation unit to another you indeed invoke undefined behavior.
Most compilers do allow a number of changes without the need for recompilation, however the list is small... and for this one I would say that it might not be possible, depending on the a priori knowledge of the derived classes.
The problem I foresee lies with the optimization that compilers usually carry out on the virtual tables.
When you create a class with virtual functions, you get a virtual table that looks like so:
In order to gain some space, the derived class own virtual functions are usually "appended":
This way a
D
object only has one virtual pointer, than can be used as such even when the type is (statically) aB
(through pointer or reference).However, if you were to extend
B
without recompilingD
, then it would just plain crash, since when calling theN+1
function ofB
you would instead call theN+1
function ofD
which would probably not even have the same arguments... oups!It can be done, though, if you know than no derived class add any virtual function of its own.