-1

派生クラスインスタンスで継承されたメソッドを呼び出す場合、コードでvtableを使用する必要がありますか?または、メソッド呼び出しを「静的」にすることもできます(それが単語の正しい使用法であるかどうかはわかりません)

例えば:

Derived derived_instance;
derived_instance.virtual_method_from_base_class();

私はmsvcを使用していますが、ほとんどの主要なコンパイラーはこれをほぼ同じ方法で実装していると思います。

私は(今)その振る舞いが実装固有であることを知っています、私は実装について興味があります。

編集:

私たちが興味を持っている理由は、関数が何度も呼び出されることであり、非常に単純であり、関数自体を編集することは許可されていないため、可能かどうか疑問に思っていたことを付け加えておきます。 、とにかく動的ディスパッチを排除することにメリットがある場合。

皆さんがオプトマイゼーションについて背を向ける前に、関数などのプロファイルを作成してカウントしました。

4

3 に答える 3

3

どちらの例でも、Derivedを受け入れるコンストラクターがあり、の新しいインスタンスBase作成する必要があります。そのようなコンストラクターがあり、これが必要なものであると仮定すると、コンパイラーは「おそらく」動的オブジェクトタイプを静的に判別し、仮想呼び出しを回避できます(そのような最適化を行うことを決定した場合)。Derived

動作は未定義ではなく、実装固有であることに注意してください。2つの間に大きな違いがあります。

新しいインスタンスの作成を避けたい場合(または、おそらくそれはあなたが望むものではない)、参照キャストを使用できますが、static_cast<Derived&>(base_instance).virtual_method_from_base_class();それは新しいオブジェクトの作成を避けますが、仮想呼び出しを避けることはできません。

本当にコンパイル時にキャストしたい場合は、CRTP http://en.wikipedia.org/wiki/Curiously_recurring_template_patternを使用すると、仮想呼び出しを避けて、コンパイル時にすべてを入力できます。

更新された質問の編集:あなたが今示した場合、私は動的タイプを静的に決定し、仮想呼び出しを回避することができる多くのコンパイラーを疑うでしょう。

于 2012-08-08T16:08:12.323 に答える
0

呼び出しを限定するだけで、仮想関数のディスパッチはありません。

Derived derived_instance;
derived_instance.Derived::virtual_method_from_base_class();

ただし、それは時期尚早の最適化になると思います。

測定してください。

于 2012-08-08T16:31:40.983 に答える
0

Vtableは、ポインターまたは参照を使用する場合にのみ機能します。オブジェクトの場合、呼び出されるのは常に特定のクラスメソッドです。

于 2012-08-08T16:07:08.037 に答える