我正在开发一个共享库。假设我有以下类定义:
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/