仮想機能と純粋仮想機能の違い

著者: Laura McKinney
作成日: 2 4月 2021
更新日: 13 5月 2024
Anonim
Fiction and Simulation [JP]
ビデオ: Fiction and Simulation [JP]

コンテンツ


仮想関数と純粋仮想関数はどちらも実行時多態性の概念です。 「仮想機能」 そして 「純粋な仮想機能」 「仮想関数」の定義は基本クラスで定義されており、継承派生クラスでも再定義されています。純粋仮想関数の基本クラスには定義がなく、継承する派生クラスはすべてそれを再定義する必要があります。

ただし、呼び出される関数は、使用されるオブジェクトのタイプに応じてランタイムで指定されるため、仮想関数は動的ディスパッチおよびランタイムディスパッチとも呼ばれます。

多態性は、C ++言語とJava言語の両方でサポートされています。 Javaでは、仮想関数はC ++の用語であるため、「オーバーライド」という用語が「仮想関数」の代わりに使用されます。

  1. 比較表
  2. 定義
  3. 主な違い
  4. 結論

比較表

比較の根拠仮想機能純粋な仮想機能
ベーシック仮想関数の定義は基本クラスにあります。Pure Virtual Functionの基本クラスには定義がありません。
宣言仮想funct_name(parameter_list){。 。 。 。 。};仮想funct_name(parameter_list)= 0;
派生クラスすべての派生クラスは、基本クラスの仮想関数をオーバーライドする場合としない場合があります。すべての派生クラスは、基本クラスの仮想関数をオーバーライドする必要があります。
効果

仮想機能は本質的に階層的です。派生クラスが基本クラスの仮想関数をオーバーライドしない場合、コンパイルには影響しません。すべての派生クラスが基本クラスの仮想関数をオーバーライドできない場合、コンパイルエラーが発生します。
抽象クラスコンセプトはありません。クラスに少なくとも1つの純粋仮想関数が含まれる場合、抽象と宣言されます。


仮想機能の定義

仮想関数 は、基本クラスのメンバー関数であり、基本クラスを継承する派生クラスによって再定義されます。すべての継承派生クラスが仮想関数を再定義する必要はありません。機能を必要とする可能性のある派生クラスによってのみ再定義されます。仮想関数は、キーワードを前に付けて基本クラスで関数を宣言することにより作成されます 'バーチャル'.

宣言:

クラスbase {public:仮想型funt_name(parameter-list){。 。 。 }};

継承された派生クラスは、「仮想」キーワードなしで仮想関数を再定義できます。派生クラスは、タスクを実行するために仮想関数を再定義します。仮想関数は派生クラスで再定義されるため、同じ関数の複数の形式があります。現在、どのバージョンの関数が呼び出されているかは、その関数を呼び出すために参照されるオブジェクトの種類によって異なります。

マルチレベルの継承

基本クラスから仮想関数を継承した派生クラスが別の派生クラスの基本クラスとして使用される場合、マルチレベルの継承では、仮想関数をオーバーライドできます。したがって、仮想関数が継承されると、その仮想的な性質も継承されます。

仮想関数も本質的に階層的です。つまり、派生クラスが基本クラスから継承した仮想関数をオーバーライド/再定義せず、派生クラスのオブジェクトがその仮想関数を呼び出すと、基本クラスによって定義された仮想関数が呼び出されます。

純粋仮想機能の定義

上記のように、派生クラスが仮想関数をオーバーライドしない場合、基本クラスによって定義された仮想関数が使用されます。しかし、基本クラス自体が仮想関数を定義していない場合はどうでしょう。多くの場合、基本クラスには仮想関数の定義がありません。または、すべての派生クラスで仮想関数をオーバーライドする必要がある場合があります。

上記の2つの状況を処理するために、C ++は「純粋な仮想機能「。 「純粋な仮想関数」は基本クラスで宣言されていますが、基本クラスでは定義されていません。純粋仮想関数は次のように宣言されます。


仮想タイプfunct_name(parameter_list)= 0;

基本クラスの仮想関数が「純粋」にされるたびに、各派生クラスは基本クラスの純粋な仮想関数を強制的にオーバーライドする必要があります。派生クラスが基本クラスの純粋仮想関数のオーバーライドに失敗すると、コンパイルエラーが発生します。

抽象クラス

少なくとも1つの純関数を含むクラスは、「抽象クラス」と呼ばれます。抽象クラスのオブジェクトは作成できませんが、抽象クラスへの参照とポインターを作成できます。抽象クラスのメンバーは、抽象基本クラスを継承する派生クラスのオブジェクトを介してアクセスできます。

抽象を宣言するクラス。キーワードを使用します '抽象' の前に 'クラス' キーワード。

//たとえば、抽象クラスclass-name {。 。仮想タイプfunct_name(parameter_list)= 0; 。 。 };

  1. 仮想関数は基本クラスで確実に定義され、派生クラスで再定義(オーバーライド)されます。一方、基本クラスの純粋仮想関数は、基本クラスで特に定義されていません
  2. 必要に応じて派生クラスは仮想関数を再定義(オーバーライド)しますが、純粋仮想関数の場合は派生クラスは純粋仮想関数を確実に再定義する必要があります。
  3. 派生クラスが仮想関数の再定義(オーバーライド)に失敗した場合、基本クラスの仮想関数を使用できます。逆に、派生クラスが純粋な仮想関数をオーバーライドできない場合、コンパイルエラーが発生します。
  4. 仮想関数を含む基本クラスをインスタンス化できます。つまり、オブジェクトを作成できます。反対に、純粋な仮想関数を含む基本クラス、つまり抽象クラスは、抽象クラスが完全に定義されていないためインスタンス化できません。

注意:
「仮想機能」と「純粋な仮想機能」のプロトタイプは、プログラム全体を通して同じままです。

結論:

「仮想関数」と「純粋仮想関数」の両方に重要性があります。「仮想関数」のように、すべての派生クラスは仮想関数を再定義する必要がなく、すべての派生クラスが仮想関数を再定義する必要がある場所、純粋仮想機能が最適です。