2

共有ライブラリ(または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の特定のエントリに異なる値が含まれるようになることです。これは正しいです?

また、現在私のライブラリを使用しているアプリケーションはどれもそのメソッドを使用していないと確信しています。これは、完全に壊れており、機能しないためです。したがって、基本メソッドの実装に対する既存の呼び出しを壊すことについて心配する必要はありません。他に何も壊さないようにしたいと思います。

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 に答える