2016-08-14 5 views
0

たとえば、Foo()がクラスBarの仮想メソッドである場合、継承するクラスはなく、コンパイラは、タイプがBar(たとえば、Bar.Foo())であることをコンパイル時に推論することができます。 コンパイル時に、Bar::Foo()が唯一可能なメソッドであることは明らかです。コンパイラは一般的に仮想メソッドの参照を最適化しますか?仮想メソッド呼び出しが最適化されているインスタンスがありますか?

+0

これはコンパイラ依存です –

+0

これは実装に依存しますが、私はほぼすべての合理的なコンパイラが実際にこの最適化を行うと確信しています。 – lisyarus

+0

"継承クラスはありません"これはほとんど検証できません。 –

答えて

2

はい、そのような場合はBar.Foo()コールが最適化されます。 Hereは、そのような呼び出しがどのようにGCCコンパイラによってインライン化されるかの説明です。

GCCの開発者HonzaHubičkaからの記事のシリーズ全体が低レベルで実装されているかdevirtualization、それが持っているものの制限事項について説明します。

0

仮想呼び出しを削除するコンパイラの最適化は、devirtualisationと呼ばれます。コンパイラは、特定のオーバーロードが呼び出されていることを知るために、インスタンスの正確な型を知る必要があります。

あなたがそのようなクラスを持っていると仮定して、finalを使用することをお勧めします。これは、クラスが継承できないことを示したり、継承しているクラスがこの特定のメソッドをオーバーライドできないことを示します。

これらはすべてあなたのコンパイラに依存しますが、これはすでにある程度使用されています。

この最適化の大きな点は、コンパイラが正確な型を知る必要があり、クラスがそれを継承しないか、メソッド呼び出しをオーバーライドできないことを推測できることです。クラスに可視性が隠されている場合、LTOはメソッドが一度しか実装されていないことを知ることができましたが、まだ実装されていません。

関連する問題