私が理解しているように、すべてのメンバー関数は D では仮想ですが、オーバーライドされていないことを確認した場合、コンパイラは自由に関数を非仮想にすることができます。
私がはっきりしていないのは、メンバー関数がオーバーライドされていないモジュールをコンパイルし、そのモジュールをメンバー関数をオーバーライドする別の場所にインポートするとどうなるかです。元のモジュールを再コンパイルするとは思わない。外部リンケージを持つメンバー関数はすべて仮想であると単純に想定していますか?
私が理解しているように、すべてのメンバー関数は D では仮想ですが、オーバーライドされていないことを確認した場合、コンパイラは自由に関数を非仮想にすることができます。
私がはっきりしていないのは、メンバー関数がオーバーライドされていないモジュールをコンパイルし、そのモジュールをメンバー関数をオーバーライドする別の場所にインポートするとどうなるかです。元のモジュールを再コンパイルするとは思わない。外部リンケージを持つメンバー関数はすべて仮想であると単純に想定していますか?
すべてのDメンバー関数はデフォルトで仮想です。最適化として実際に関数を非仮想化するコンパイラは存在しないと思います。ただし、クラスまたは関数を「final」としてマークすることにより、手動で行うことができます。
これがどのように実装されるかは、コンパイラおよびリンカー固有です。しかし、仮想関数呼び出しを最適化して取り除くことができる一般的な状況の 1 つは、ローカルでインスタンス化されたクラスがある場合です。クラスの型はコンパイル時に完全に認識されるため、関数呼び出しはこのスコープ内で直接実行できます。これは、コンパイラ レベルで実行できます。
これに加えて、リンカーが関数の実装が決してオーバーライドされないことに気付いた場合、リンカーは最適化を行い、仮想関数呼び出しをそのクラスの直接関数呼び出しに置き換えることができます。特に、クラスが派生していない場合は、メンバー関数へのすべての呼び出しを直接実行できます。リンカが「final」キーワードを可能な限り挿入するかのようです。(リンカーは、関数が他のライブラリまたは実行可能ファイルでオーバーライドされているかどうかを認識しないため、エクスポートされたクラスおよび関数にこの最適化を適用しない場合があります。)
FeepingCreature は、仮想化できないテンプレート化された関数を除いて、ほとんど正しいです。