仮想と非仮想
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/29 19:11 UTC 版)
「メソッド (計算機科学)」の記事における「仮想と非仮想」の解説
C++では、一般に仮想関数はコンパイル時にどのメンバー関数を呼び出すかを確定できないため、通常の非仮想なメンバー関数呼び出しよりもパフォーマンスが悪いというデメリットがある。そのため、パフォーマンスを気にするC++プログラマには、継承する必要がないクラスのメンバー関数(特にデストラクタを含む)にvirtual修飾子をつけることを非常に嫌う傾向がある。また、C++にはtemplateという機能が存在し、多くの場合仮想関数はtemplateで代用できてしまうため仮想関数にこだわる必要がないという事情もある[疑問点 – ノート]。ただし、デストラクタが非仮想の場合、派生クラスのインスタンスのポリモーフィックなdeleteが不可能となる、という利便性および安全上のデメリットも発生する。 メソッドがデフォルトで非仮想というC++に準ずる設計選択をしたC#においても、仮想メソッドの呼び出しには非仮想メソッドよりもコストがかかることを念頭に置いて利用する必要がある。 Javaのインスタンスメソッドは常に仮想であるが、クラスメソッド(静的メソッド)はオーバーライドすることのできない非仮想であるため、静的メソッドのほうが呼び出しコストが小さく、パフォーマンス上のメリットがある。 Javaのfinal修飾子は、パフォーマンス上の理由というよりはむしろ、派生クラスでの不用意なオーバーライドを禁止してバグを未然に防止することにある。「Javaではメソッドをfinal修飾することでコンパイラの最適化によりパフォーマンスが向上する」という神話があるが、一方で、Java仮想マシンの性能によってはメソッドをfinalと宣言したからといって優れたパフォーマンスが得られるとは限らないという指摘もある。なお、OracleのHotSpot VMは、finalメソッドを検出して非常に効率よく実行できるように最適化されていると説明されている。
※この「仮想と非仮想」の解説は、「メソッド (計算機科学)」の解説の一部です。
「仮想と非仮想」を含む「メソッド (計算機科学)」の記事については、「メソッド (計算機科学)」の概要を参照ください。
- 仮想と非仮想のページへのリンク