4

自分で作成できる.dllがあります。ライブラリ内のクラスLionから派生したクラスがあります。Catこれは仮想関数をオーバーライドしますLeap()。タイプのオブジェクトを作成しLion、タイプを期待するライブラリ関数に渡します。Catたとえば、を呼び出すときにCat->Leap()、オーバーライドされた仮想関数を使用しますLion->Leap()

これは可能ですか?

これまでに試したことはすべて、オーバーライドされた関数が無視されることになりました。これは、ライブラリがコンパイルされるとLeap()、への呼び出しを解決する方法がわかるためだと思います。その時点では、派生型は存在しません。または、ライブラリがタイプのオブジェクトCat(実際にはタイプ)を参照しているため、。ではなく、Lionを呼び出します。Cat::Leap()Lion::Leap()

関数が仮想であるという事実は、ライブラリ内から呼び出されていても、実行時にオブジェクトのvtableを確認することで呼び出しを解決することを意味すると思いました。これは、派生関数の場合です。タイプ。

ありがとう。

4

3 に答える 3

2

これを機能させるには、ライブラリを特定の方法で作成する必要があります。ライブラリはCat、値ではなく、参照またはポインタによって s を取得する必要があります (残念ながら、C++ でパラメータが渡されるデフォルトの方法です)。by 値Lionを期待する関数に aを渡すと、は aにスライスされ、関数に関する限り効果的に a になります。CatLionCatCat

于 2012-05-25T15:27:42.893 に答える
0

ライブラリのヘッダー ファイルで仮想飛躍を宣言します。

class Cat {
public:
  virtual void leap() const { /* ... */ };
  /// ...
};

Catライブラリのソースコードで参照またはポインタを渡すことで sを使用します。

void LibraryUsesCat(const Cat*c)
{ c-> leap(); }

アプリケーションで仮想関数をオーバーライドします。

class Lion : public Cat {
public:
  void leap() const { /* ... */ }
  /// ...
};

これはうまくいくはずです。

于 2012-05-25T16:33:00.883 に答える
0

仮想関数は、実行時に決定される動的/遅延バインディングを有効にします。したがって、このようなコードに影響を与えるコンパイル時の決定について心配する必要はありません。

関数が基本クラスで仮想であり、派生クラスでオーバーライドされ、ライブラリ関数が const 参照またはポインターを介して呼び出される限り、クラスが定義されている場所に関係なく正常に機能します。

ポインターや参照ではなく値で渡しているため、オブジェクトをスライスして基本クラスの半分だけになってしまう可能性があります。

次のように考えてください。

値によってライオンを猫として渡すと、ライオンがキャストされた「猫」のコピーが作成されます。そのコピーが使用されますが、そのコピーは猫の半分だけのものであったため、ライオンの半分にディスパッチすることはできません。コピーには存在しません。これらの関数とデータ メンバーは単に存在しません。参照またはポインターで渡すことで、元のライオン オブジェクト全体を利用できるようになります。

于 2012-05-25T15:33:44.857 に答える