抽象クラス (C++ のみ)

抽象クラス とは、 特に基底クラスとして使用するように設計されたクラスです。 抽象クラスには、少なくとも 1 つの純粋仮想関数 が含まれています。 クラス宣言の中の仮想メンバー関数の宣言で、純粋指定子 (= 0) を使用することによって、純粋仮想関数を宣言することができます。

次に抽象クラスの例を示します。
class AB {
public:
  virtual void f() = 0;
};
関数 AB::f は、純粋仮想関数です。 関数宣言に、純粋指定子と定義の両方を入れることはできません。 例えば、コンパイラーは以下のコードを許可しません。
struct A {
  virtual void g() { } = 0;
};
抽象クラスをパラメーター型、関数からの戻りの型、または明示型変換の型として使用することはできませんし、 抽象クラスのオブジェクトも宣言することはできません。 ただし、抽象クラスを指すポインター、および参照を宣言することは可能です。 次の例は、このことを示しています。
struct A {
  virtual void f() = 0;
};

struct B : A {
  virtual void f() { }
};

// Error:
// Class A is an abstract class
// A g();

// Error:
// Class A is an abstract class
// void h(A);
A& i(A&);

int main() {

// Error:
// Class A is an abstract class
//   A a;

   A* pa;
   B b;

// Error:
// Class A is an abstract class
//   static_cast<A>(b);
}
クラス A は、抽象クラスです。 コンパイラーは、関数宣言 A g() または void h(A)、 オブジェクト a の宣言、そして b の型 A への静的キャストも許可しません。

仮想メンバー関数は、継承されます。 派生クラスにある各純粋仮想関数をオーバーライドしない限り、 抽象基底クラスから派生するクラスも抽象になります。

以下に例を示します。
class AB {
public:
  virtual void f() = 0;
};

class D2 : public AB {
  void g();
};

int main() {
  D2 d;
}

コンパイラーは、オブジェクト d の宣言を許可しません。 D2 が、AB から純粋仮想関数 f() を継承した抽象クラスだからです。 関数 D2::f() を定義すると、コンパイラーは、オブジェクト d の宣言を許可します。これが、継承された純粋仮想関数 AB::f() をオーバーライドするからです。 D2 の抽象化を避けたい場合には、 関数 AB::f() をオーバーライドする必要があります。

非抽象クラスから抽象クラスを派生させたり、 非純粋仮想関数を純粋仮想関数でオーバーライドできることに注意してください。

抽象クラスのコンストラクターまたはデストラクターから、メンバー関数を呼び出すことができます。 ただし、コンストラクターから純粋仮想関数を呼び出した (直接または間接) 結果は、未定義です。 次の例は、このことを示しています。
struct A {
  A() {
    direct();
    indirect();
  }
  virtual void direct() = 0;
  virtual void indirect() { direct(); }
};
A のデフォルトのコンストラクターは、直接的、および間接的 (indirect() を介して) の両方で、純粋仮想関数 direct() を呼び出します。