纯虚函数和二进制兼容性 [英] Pure virtual functions and binary compatibility

查看:159
本文介绍了纯虚函数和二进制兼容性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我知道向非叶类添加新的虚函数通常是不好的,因为它破坏了没有重新编译的任何派生类的二进制兼容性。但是,我有一个稍微不同的情况:

Now, I know it is generally bad to add new virtual functions to non-leaf classes as it breaks binary compatibility for any derived classes which haven't been recompiled. However, I have a slightly different situation:

我有一个接口类和实现类编译成共享库,例如:

I have an interface class and implementation class compiled into a shared library, for example:

class Interface {
    public:
        static Interface* giveMeImplPtr();
        ...
        virtual void Foo( uint16_t arg ) = 0;
        ...
}

class Impl {
    public:
        ...
        void Foo( uint16_t arg );
        ....
}



我的主应用程序使用此共享库,可以基本上写成:

My main application uses this shared library, and could basically be written as:

Interface* foo = Implementation::giveMeImplPtr();
foo->Foo( 0xff );

换句话说,应用程序没有任何派生自

In other words, the application doesn't have any classes which derive from Interface, it merely uses it.

现在,我想重载 Foo(uint16_t arg) Foo(uint32_t arg),我可以安全地做:

Now, say I want to overload Foo( uint16_t arg ) with Foo( uint32_t arg ), am I safe to do:

 class Interface {
    public:
        static Interface* giveMeImplPtr();
        ...
        virtual void Foo( uint16_t arg ) = 0;
        virtual void Foo( uint32_t arg ) = 0;
        ...
}

并重新编译我的共享库,无需重新编译应用程序?

and recompile my shared library without having to recompile the application?

如果是这样,有什么不寻常的注意事项我需要注意吗?如果没有,我有没有任何其他选项,除了击中和升级版本库,从而打破向后兼容性?

If so, are there any unusual caveats I need to be aware of? If not, do I have any other options other than to take the hit and up-version the library, thus breaking backwards compatibility?

推荐答案

p> ABI基本上取决于对象的大小和形状,包括vtable。添加一个虚函数肯定会改变vtable,并且它的变化取决于编译器。

ABI basically depends on the size and shape of the object, including the vtable. Adding a virtual function will definitely change the vtable, and how it changes depends on the compiler.

在这种情况下要考虑的是,你不只是提出ABI中断更改,但是API打破了在编译时很难检测的API。如果这些不是虚拟函数和ABI兼容性不是一个问题,在您的更改后,像:

Something else to consider in this case is that you're not just proposing an ABI breaking change, but an API breaking one that is very difficult to detect at compile time. If these were not virtual functions and ABI compatibility wasn't an issue, after your change, something like:

void f(Interface * i) {
  i->Foo(1)
}

会静默地调用你的新函数,但是只有当代码被重新编译,这可能使调试非常困难。

will quietly end up calling your new function, but only if that code is recompiled, which can make debugging very difficult.

这篇关于纯虚函数和二进制兼容性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆