仮想オーバーライドとバイナリの互換性
-
28-10-2019 - |
質問
共有ライブラリ(またはWindowsでDLL)としてコンパイルできるライブラリがあります。別のライブラリの別のクラスから派生したクラスがあります。基本クラスにはいくつかの仮想方法があり、私のクラスはそれらのいくつかを無効にします。例えば:
class Base {
public:
virtual void method1();
virtual void method2();
virtual void method3();
};
class Derived: public Base {
public:
virtual void method2();
};
今、私は仮想的な方法の1つが私のクラスではうまく機能しないことを理解しました。現在、この方法をオーバーライドしていないので、その動作を修正するためにそれをオーバーライドしたいと思います。
class Derived: public Base {
public:
virtual void method2();
virtual void method3();
};
これにより、私のライブラリの古いバージョンとのバイナリの互換性が壊れますか?
私が理解する限り、Vtableの仮想メソッドの数と順序が同じままであるため、仮想関数を追加するだけでは異なります。唯一の違いは、私のクラスのVtableの特定のエントリに異なる値が含まれることです。これは正しいです?
また、私のライブラリを使用しているアプリケーションは、完全に壊れており、機能しないため、その方法を使用しているアプリケーションはないと確信しています。したがって、既存のコールをベースメソッドの実装に壊すことを心配していません。他に何も壊れないようにしたいだけです。
解決
DLLについて話しているので、これはVisual Studio/WindowsのC ++であると思います。オーバーライドを追加しても、Vtableのサイズが変更されていないため、バイナリの互換性が破壊されません。ただし、派生の新しいインスタンスをインスタンスするすべてのコードを再コンパイルしないと、望ましくない結果を引き起こす可能性があります。これは、vtableが派生したクラスのソースではなく、インスタンス化ソースによって初期化されるためです。
他のヒント
私が正しく理解した場合、あなたはDLL1にあなたの基本クラスと派生クラスをDLL2に持っています。これが当てはまる場合、あなたが説明する変更はDLL1に影響しません。更新されたDLL2をインストールすると仮定すると、アプリケーションはポインターまたはベースへの参照を介して派生のインスタンスにアクセスするたびに、派生:: method3()を呼び出します。
派生クラス(新しい仮想メソッドを追加した)のライブラリは、willに存在します いいえ 必然的にライブラリの古いバージョンと互換性があるバイナリ(ABI)。これは、オーバーライドされた仮想メソッドを追加するときに、コンパイラによってVtableがどのように生成されるかを制御できないためです。