c++ - 未使用的私有(private)虚拟方法是否允许在不破坏 ABI 兼容性的情况下进行 future 扩展?

标签 c++ virtual backwards-compatibility

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

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# 虚拟方法不会在客户端代码中被覆盖,也不会从任何地方调用。它们充当 future 扩展的占位符。假设我将其中一个保留方法替换为具有不同签名和实现的虚函数:

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 的别名?

最佳答案

由于函数 reserved1 只是为了保持 vtable 布局兼容性,所以客户端代码中可能不会调用它。

如果它没有被调用,客户端代码不需要任何链接器引用它:这显然是所有特定于平台的,但通常你的方案应该工作正常。

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

关于c++ - 未使用的私有(private)虚拟方法是否允许在不破坏 ABI 兼容性的情况下进行 future 扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9352094/

相关文章:

c++ - 如何通过指针访问数组的元素?

虚函数上的 C++ 多态性

c++ - 我需要分发哪个版本的可再发行版本?

c++ - 当矩阵没有 LU 分解时,如何在 C++ 中求解方阵的线性系统?

c++ - LoadString() 方法在 C++ 中不起作用

c++ - 对象是否会通过kill正确地被销毁?

c++ - 类模板 C++ 中的虚方法模板

java - 如何在选项卡中使用 Parse.com 列表?

c# - 始终从 GAC 获取最新的 dll

Java JDK 11 打破旧的 Jars/程序