抽象クラス (C++)
抽象クラスは一般的な概念を表現したもので、このクラスからより具体的なクラスを派生するために使用できます。 抽象クラス型のオブジェクトを作成できません。 しかし、抽象クラス型へのポインターと参照を使用できます。
抽象クラスを作成するには、少なくとも 1 つの純粋仮想メンバー関数を宣言します。 これは、純粋な指定子 (= 0
) の構文を使用して宣言される仮想関数です。 抽象クラスから派生したクラスは純粋仮想関数を実装する必要があります。つまり派生クラスも抽象クラスです。
「仮想関数」に示されている例を考えます。 Account
クラスの目的は一般的な機能を提供することですが、Account
型のオブジェクトは一般的すぎて役に立ちません。 したがって、Account
は抽象クラスに適した候補です。
// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
この宣言と前の宣言の唯一の違いは、PrintBalance
が純粋指定子 (= 0
) で宣言されていることです。
抽象クラスに関する制約
抽象クラスは以下の項目では使用できません。
変数またはメンバー データ
引数の型
関数の戻り値の型
明示的な変換の型
抽象クラスのコンストラクターが純粋仮想関数を直接または間接的に呼び出すと、結果が未定義になります。 ただし、抽象クラスのコンストラクターとデストラクターは、他のメンバー関数を呼び出すことができます。
純粋仮想関数を定義する
抽象クラスの純粋仮想関数は、定義することもできますし、実装もあります。 次のように、完全修飾構文を使用する場合に限り、この種の関数を呼び出ことができます。
abstract-class-name::function-name()
純粋仮想関数を定義することは、基底クラスに純粋仮想デストラクターが含まれるクラス階層を設計する場合に役立ちます。 その理由は、オブジェクトの破棄中には基底クラスのデストラクターが必ず呼び出されるからです。 次の例を考えてみましょう。
// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
base() {}
// To define the virtual destructor outside the class:
virtual ~base() = 0;
// Microsoft-specific extension to define it inline:
// virtual ~base() = 0 {};
};
base::~base() {} // required if not using Microsoft extension
class derived : public base
{
public:
derived() {}
~derived() {}
};
int main()
{
derived aDerived; // destructor called when it goes out of scope
}
この例は、Microsoft コンパイラ拡張機能で、純粋仮想 ~base()
にインライン定義を追加する方法を示しています。 base::~base() {}
を使用してクラス外で定義することもできます。
オブジェクト aDerived
がスコープ外の場合、クラス derived
のデストラクターが呼び出されます。 コンパイラは、デストラクター derived
の後にクラス base
のデストラクターを暗黙的に呼び出すコードを生成します。 純粋仮想関数 ~base
の空の実装は、その関数に対して少なくとも実装が存在することを保証します。 存在しないと、リンカーは暗黙的な呼び出しに対する未解決の外部シンボル エラーを生成します。
Note
前の例では、純粋仮想関数 base::~base
は、derived::~derived
から暗黙的に呼び出されます。 完全修飾メンバー関数名を使用して、純粋仮想関数を明示的に呼び出すこともできます。 この種の関数には実装が必要です。実装がない場合は、呼び出しを行うとリンク時にエラーが発生します。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示