我有一个可以编译为共享库(或Windows中的DLL)的库。它有一个派生自另一个库中另一个类的类。基类有一些虚方法,我的类会覆盖其中的一些。例如:
class Base {
public:
virtual void method1();
virtual void method2();
virtual void method3();
};
class Derived: public Base {
public:
virtual void method2();
};
现在我发现其中一个虚拟方法并不适用于我的课程。目前它不会覆盖此方法,因此我也想覆盖它以修复其行为:
class Derived: public Base {
public:
virtual void method2();
virtual void method3();
};
这会破坏我的库的旧版本的二进制兼容性吗?
据我了解,它与仅添加虚函数不同,因为vtable中虚拟方法的数量和顺序保持不变。唯一的区别是我的类的vtable中的特定条目现在将包含不同的值。这是对的吗?
我也很确定当前使用我的库的应用程序都没有使用该方法,因为它完全被破坏而且永远无法运行。所以我不担心破坏对基本方法实现的现有调用。我只是想确保我不会破坏其他任何东西。
答案 0 :(得分:3)
由于你在谈论DLL,我认为这是Visual Studio / Windows中的C ++。添加覆盖不会破坏二进制兼容性,因为vtable的大小不会改变。但是,如果不重新编译实例化Derived新实例的所有代码,则可能会导致一些不希望的结果。这是因为vtable是由实例化源初始化的,而不是实现Derived的类的源。
答案 1 :(得分:0)
如果我理解正确,你在Dll1中有你的Base类,在Dll2中有你的Derived类。如果是这种情况,您描述的更改不会影响Dll1。假设您将安装更新的Dll2,只要您通过指针或对Base的引用访问Derived实例,您的应用程序就会切换到调用Derived :: method3()。
答案 2 :(得分:0)
你的派生类(添加了新的虚方法)所在的库 not 必然是二进制(ABI)兼容旧版本的库。这是因为在添加重写的虚拟方法时,无法控制编译器如何生成vtable。