我正在开发一个共享库。假设我有以下类定义:
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_;
};
The reserved#
虚拟方法不会在客户端代码中被重写,也不会从任何地方调用。它们充当未来扩展的占位符。假设我用具有不同签名和实现的虚拟函数替换了其中一个保留方法:
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 布局兼容性,大概客户端代码中没有任何内容会调用它。
如果它不被称为客户端代码,则不需要任何链接器引用它:这显然是特定于平台的,但一般来说,您的方案应该可以正常工作。
虚拟方法真的是私有的吗?如果他们不能被召唤or从客户端覆盖,您可以公开一个不透明的前向声明并将实现完全保留在动态库中(例如,MyClass::PImpl
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)