虚拟覆盖和二进制兼容性
Virtual override and binary compatibility
我有一个可以编译为共享库(或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();
};
这会破坏我的库与旧版本的二进制兼容性吗?
据我所知,这与仅仅添加虚函数不同,因为虚函数表中虚方法的数量和顺序保持不变。唯一的区别是,我的类的虚函数表中的一个特定条目现在将包含一个不同的值。这是正确的吗?
我也很确定目前使用我的库的应用程序都没有使用该方法,因为它完全被破坏了,从来没有工作过。所以我不担心会破坏对基方法实现的现有调用。我只是想确保我不会破坏任何东西
既然你在谈论dll,我假设这是Visual Studio/Windows中的c++。添加覆盖不会破坏二进制兼容性,因为虚函数表的大小不会改变。但是,如果不重新编译所有实例化派生的新实例的代码,可能会导致一些不期望的结果。这是因为虚函数表是由实例化源初始化的,而不是由实现派生类的源初始化的。
如果我理解正确,你在Dll1中有你的基类,在Dll2中有你的派生类。如果是这种情况,你所描述的变化不会影响Dll1。假设您将安装更新后的Dll2,那么每当您通过指针或对Base的引用访问Derived的实例时,应用程序将切换为调用Derived::method3()。
您的派生类(添加了新的虚方法)所在的库将不一定是与旧版本库兼容的二进制(ABI)库。这是因为当您添加被覆盖的虚方法时,您无法控制编译器如何生成虚表。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 添加noexcept是否会破坏二进制兼容性
- 在Qt中使用C++Lambda函数作为插槽是否有助于保持库的二进制兼容性?
- 为什么新的虚拟函数不会破坏二进制兼容性的现象?
- 在类中添加新的成员变量会影响二进制兼容性
- 2015年视觉工作室的二进制兼容性
- 保证C++库二进制兼容性的简单方法,C链接
- 添加move构造函数会破坏二进制兼容性吗
- 关于 Linux 的二进制兼容性
- 我们什么时候打破二进制兼容性
- Linux二进制兼容性
- 可以添加静态变量破坏 Linux 上的二进制兼容性
- 使用按引用传递而不是按指针传递时的二进制兼容性
- 旧发行版上的二进制兼容性(使用C++11)
- 在C++中更改参数名称时的二进制兼容性
- 不同类中相同结构定义的二进制兼容性
- 内联如何限制升级版本的二进制兼容性
- VS2010和VS2012之间的二进制C++库兼容性
- 由于虚拟函数,二进制兼容性中断
- 更改方法以添加隐藏的this指针是否会破坏二进制兼容性