2009-04-15 8 views
6

私が理解しているように、すべてのメンバ関数はDでは仮想ですが、コンパイラはオーバーライドされないと見なしても関数を非仮想にすることは自由です。メンバー関数がDで仮想であることを保証する方法はありますか?

私が明確にしていないのは、メンバー関数をオーバーライドしないモジュールをコンパイルし、そのモジュールをメンバ関数をオーバーライドする別の場所にインポートする場合です。私はそれが元のモジュールを再コンパイルするとは思わない。外部リンケージを持つ任意のメンバー関数が仮想であると単純に仮定していますか?

答えて

5

デフォルトでは、すべてのDメンバー関数は仮想です。私は実際に最適化として非仮想関数を作るコンパイラはないと思います。クラスや関数を "final"としてマークすることで、手動で行うこともできます。

1

私はFeepingCreatureが正しいと信じていますが、ソースから実行可能ファイルを直接作成する場合、コンパイラはそのような最適化だけを考慮することができます。

2

FeepingCreatureは、仮想化できないテンプレート関数を除いて、ほとんど正しいです。

2

これはどのように実装されているのですか?コンパイラとリンカに固有です。しかし、仮想関数呼び出しを最適化できる共通の状況の1つは、クラスをローカルでインスタンス化するときです。コンパイル時にクラスの型が完全に分かっているため、このスコープ内で関数呼び出しを直接実行できます。これはコンパイラレベルで行うことができます。

さらに、リンカが関数の実装をオーバーライドしないと認識した場合、リンカは最適化を行い、仮想関数呼び出しをそのクラスの直接関数呼び出しに置き換えることがあります。特に、クラスが決して導出されない場合、メンバー関数へのすべての呼び出しは直接実行できます。リンカが可能な限り 'final'キーワードを挿入するかのようです。リンカーは、関数が他のライブラリや実行可能ファイルでオーバーライドされているかどうかわからないため、エクスポートされたクラスと関数にこの最適化を適用しないことがあります。

関連する問題