2

我有一个可以编译为共享库(或 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 中的特定条目现在将包含不同的值。这个对吗?

我也很确定当前使用我的库的应用程序都没有使用该方法,因为它完全损坏并且永远无法工作。所以我不担心破坏对基本方法实现的现有调用。我只是想确保我不会破坏其他任何东西。

4

3 回答 3

3

由于您在谈论 DLL,我假设这是 Visual Studio/Windows 中的 C++。添加覆盖不会破坏二进制兼容性,因为 vtable 的大小没有改变。但是,如果您不重新编译所有实例化 Derived 新实例的代码,则可能会导致一些不希望的结果。这是因为 vtable 是由实例化源初始化的,而不是实现 Derived 的类的源。

于 2011-09-08T16:40:39.103 回答
0

如果我理解正确,您在 Dll1 中有 Base 类,在 Dll2 中有 Derived 类。如果是这种情况,您描述的更改不会影响 Dll1。假设您将安装更新的 Dll2,只要您通过指针或对 Base 的引用访问 Derived 的实例,您的应用程序就会切换到调用 Derived::method3()。

于 2011-09-08T16:41:14.110 回答
0

您的派生类(添加了新的虚拟方法)所在的库不一定是与旧版本的库兼容的二进制 (ABI)。这是因为当您添加被覆盖的虚方法时,您无法控制编译器如何生成 vtable。

于 2011-09-08T16:48:39.997 回答