C ++の仮想関数のインスタンス化の違いは何ですか?
質問
次の2つの宣言の違いは何ですか?
virtual void calculateBase() = 0;
virtual void calculateBase();
最初の(= 0)は「純粋な抽象関数」です;しかし、それが2つ目の理由は何ですか?
解決
最初のものは純粋仮想関数と呼ばれます。通常、純粋仮想関数には実装がなく、純粋仮想関数を含むクラスのインスタンスを作成することはできません。
2番目は仮想関数です(つまり、「通常の」仮想関数)。クラスはこの関数の実装を提供しますが、その派生クラスは、このメソッドの独自の実装を提供することにより、この実装をオーバーライドできます。
他のヒント
最初のものは「純粋な仮想」です。 -クラスを抽象化し、インスタンス化しようとすると、コンパイラエラーが発生します。純粋な仮想関数を実装することにより、派生クラスが必要な動作を実装する基本クラスとして使用することを意図しています。基本クラスに関数を実装する必要はありませんが、可能です。
これは、2つのデザインパターンでよく使用されるパターンです。
- "テンプレートメソッド" のデザインパターン。ベースクラスは周囲の構造を実装します関数呼び出し。ただし、関数呼び出しの詳細は、派生クラスによって入力する必要があります。
- 「インターフェース」 C ++にはinterfaceキーワードがないため、デザインパターン。抽象基本クラスは、理想的には純粋な仮想関数のみを持ち、メンバーデータを持たないことが、インターフェイスを定義するC ++の方法です。
2番目の宣言は、通常の仮想メンバー関数宣言です。基本クラスにメンバー関数を実装しないと、コンパイラエラーが発生します。まだ仮想であるため、派生クラスの動作をオーバーライドすると便利な場合があります。
最初のものは基本クラスに実装する必要はありませんが、継承クラスに実装するよう強制します。
基本クラスに2番目のクラスを実装する必要があり、継承クラスに実装できます。
基本的に、継承する場合、最初の1つをオーバーライドするには強制され、2番目のものをオーバーライドするには許可されます。
Javaから来ていますよね
用語が混在していると思います...
virtual void x() = 0;
は純粋な仮想関数、または抽象関数です。これは実装のない仮想関数です。あなたは、抽象関数のみを持つクラスについて、インターフェースに相当するc ++である純粋な抽象クラスについて話します。
virtual void x();
は仮想関数です。つまり、派生クラスで再定義できますが、抽象ではないため、実装を提供する必要があります。
virtual void calculateBase()= 0;
最初の関数は、クラスで実装を実行できない純粋な仮想関数であり、純粋な抽象クラスまたはインターフェイスクラスとして機能します。具体的な実装は、サブクラスで実行またはオーバーライドする必要があります。派生クラスへのインターフェイスクラスとして機能します。
virtual void calculateBase();
この関数は、基本クラスで実装(デフォルト)を実行できる仮想関数です。ただし、派生クラスは独自の実装をオーバーライドする必要があります。
Javaで
virtual void calculateBase() = 0;
次のようになります
abstract void calculateBase();
and
virtual void calculateBase();
次のようになります
void calculateBase();
完全に明確にするため、
final void calculateBase();
C ++では、「同じ」ですas
<*>Javaで。つまり、finalは「デフォルト」です。 C ++で。ただし、このルールには例外があります。クラスを仮想メソッドでサブクラス化し、仮想キーワードを使用せずに再実装する場合、サブクラスのメソッドは最終的なものではありません 。
2番目の関数には、それを宣言するクラスの実装(「= 0」の欠如)が必要であり、 はサブクラスによってオーバーライドできます。
最初の関数は、それを宣言するクラスに実装を持つ場合と持たない場合があり、 はサブクラスによって実装される