web-dev-qa-db-ja.com

仮想関数と純粋仮想関数の違い

重複している可能性があります:
C++仮想/純仮想の説明

純粋仮想関数と仮想関数の違いは何ですか?

私は「純粋な仮想関数はボディのない仮想関数」を知っていますが、これは何を意味するのか、そして実際には以下の行によって行われるのです。

virtual void virtualfunctioname() = 0
189

仮想関数はそのクラスを多態性基本クラスにします。派生クラスは仮想関数をオーバーライドできます。基本クラスのポインタ/参照を通じて呼び出された仮想関数は実行時に解決されます。つまり、オブジェクトの動的型静的型の代わりに使用されます。 - ):

 Derived d;
 Base& rb = d;
 // if Base::f() is virtual and Derived overrides it, Derived::f() will be called
 rb.f();  

純粋仮想関数は、宣言が=0で終わる仮想関数です。

class Base {
  // ...
  virtual void f() = 0;
  // ...

純粋仮想関数は、暗黙的にそれが定義されているクラスをabstractにします(Javaでは、クラスabstractを明示的に宣言するキーワードがあります)。抽象クラスはインスタンス化できません。派生クラスは、継承されたすべての純粋仮想関数をオーバーライドまたは実装する必要があります。そうでなければ、それらも抽象的になるでしょう。

C++の興味深い「機能」は、クラスが実装を持つ純粋な仮想関数を定義できることです。 ( 何が良いのかは議論の余地があります 。)


C++ 11では、deleteおよびdefaultキーワードが新たに使用されています。これは、純粋仮想関数の構文に似ています。

my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;

deletedefaultの使い方の詳細については、 this question および this one を参照してください。

237
sbi

仮想関数の場合は、基本クラスで実装を提供する必要があります。ただし、派生クラスはこの実装を独自の実装でオーバーライドできます。通常、純粋仮想関数の実装は提供されていません。関数宣言の最後に=0を使って関数を純粋仮想にすることができます。また、純粋仮想関数を含むクラスは抽象クラスです。つまり、このクラスのオブジェクトを作成することはできません。

29
Naveen

純粋仮想関数は通常、基底クラスには実装されていません(ただし実装できます)ので、リーフサブクラスに実装する必要があります。

次のように、宣言に "= 0"を追加することでその事実を示します。

class AbstractBase
{
    virtual void PureVirtualFunction() = 0;
}

その場合、純粋仮想関数を実装しないと、サブクラスを宣言してインスタンス化することはできません。

class Derived : public AbstractBase
{
    virtual void PureVirtualFunction() override { }
}

overrideキーワードを追加することによって、コンパイラーは同じシグニチャーを持つ基本クラス仮想関数があることを確認します。

19
Johann Gerell

C++では実際に 純粋な仮想関数の実装を提供する することができます。唯一の違いは、クラスをインスタンス化する前に、すべての純粋仮想関数を派生クラスによって実装する必要があることです。

8
AshleysBrain