未使用的私有虚拟方法是否可以在将来扩展而不破坏ABI兼容性? [英] Would unused private virtual methods allow future expansion without breaking ABI compatibility?

查看:85
本文介绍了未使用的私有虚拟方法是否可以在将来扩展而不破坏ABI兼容性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个共享库.假设我有以下类定义:

I'm developing a shared library. Let's say I have the following class definition:

class MyClass {
public:
    //public interface

private:

    virtual void foo1(int);
    virtual void foo2(int, bool);
    virtual void foo3(double);

    virtual void reserved1();
    virtual void reserved2();
    virtual void reserved3();

    class Impl;
    Impl* impl_;
};

reserved#虚拟方法不会在客户端代码中覆盖,也不会从任何地方调用.它们充当未来扩展的占位符.假设我将保留方法之一替换为具有不同签名和实现的虚函数:

The reserved# virtual methods are not overridden in the client code and not called from anywhere. They serve as placeholders for future expansion. Let's say I replace one of the reserved methods with a virtual function with different signature and implementation:

class MyClass {
public:
    //public interface

private:

    virtual void foo1(int);
    virtual void foo2(int, bool);
    virtual void foo3(double);
    virtual void foo4(int, int);

    virtual void reserved2();
    virtual void reserved3();

    class Impl;
    Impl* impl_;
};

由于vtable的布局没有变化,因此它似乎以这种方式实现了完全的二进制兼容性.问题在于旧代码仍然会要求动态链接程序解析reserved1(),并且如果该定义不在库中,则代码将在链接时崩溃,或者如果有人调用foo4,则会在运行时崩溃.由于ODR,我认为这个问题无法移植解决.也许有一种方法可以诱骗编译器生成reserved1的符号,而该符号将作为foo4的别名?

It would seem that it achieves full binary compatibility in this way, since the layout of the vtable doesn't change. The problem is that the old code would still ask the dynamic linker to resolve reserved1() and if the definition is not within the library, then the code would crash at link-time, or run-time if someone calls foo4. I assume this issue can't be solved portably, because of ODR. Maybe there's a way to trick the compiler to generate symbol of reserved1 that would act as an alias to foo4?

推荐答案

由于函数reserved1仅用于保留vtable布局兼容性,因此客户端代码中大概不会调用它.

Since the function reserved1 is only there to preserve vtable layout compatibility, presumably nothing in the client code will call it.

如果不使用它,则客户端代码不需要对其进行任何链接器引用:这显然是所有特定于平台的,但总的来说,您的方案应该可以正常工作.

If it isn't called client code doesn't need any linker reference to it: this is obviously all platform-specific, but in general your scheme should work fine.

虚拟方法真的是私有的吗?如果不能从客户端调用它们,则可以公开一个不透明的前向声明,并将实现完全保留在动态库中(例如,MyClass::PImpl).

Are the virtual methods really private though? If they can't be called or overridden from the client, you could just expose an opaque forward declaration and keep the implementation entirely inside your dynamic lib (eg, MyClass::PImpl).

这篇关于未使用的私有虚拟方法是否可以在将来扩展而不破坏ABI兼容性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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