継承 とは、既存のクラスを変更しないで、
再利用したり拡張したりするメカニズムのことです。
継承は、オブジェクトをクラスに組み込むのとほぼ同じです。 クラス A のオブジェクト x を、B のクラス定義に宣言するとします。 その結果、クラス B は、クラス A の public データ・メンバーおよびメンバー関数のすべてにアクセスできます。 しかし、クラス B では、クラス A のデータ・メンバーおよびメンバー関数にアクセスするのに、 オブジェクト x を介してアクセスする必要があります。 次の例は、このことを示しています。
#include <iostream> using namespace std; class A { int data; public: void f(int arg) { data = arg; } int g() { return data; } }; class B { public: A x; }; int main() { B obj; obj.x.f(20); cout << obj.x.g() << endl; // cout << obj.g() << endl; }
main 関数のオブジェクト obj は、 ステートメント obj.x.f(20) を使用したデータ・メンバー B::x を介して、 関数 A::f() にアクセスします。 オブジェクト obj は、同様な方法で、 ステートメント obj.x.g() で A::g() にアクセスします。 コンパイラーは、g() がクラス A のメンバー関数であり、 クラス B のメンバー関数ではないので、ステートメント obj.g() を許可しません。
継承メカニズムにより、上記の例で示した obj.g() のようなステートメントを使用できます。 ステートメントを有効にするには、 g() が、クラス B のメンバー関数である必要があります。
継承により、別のクラスのメンバーの名前および定義を、 新規クラスの一部としてインクルードできます。 新規クラスにインクルードしたいメンバーを持つ元のクラスは、基底クラス と呼ばれます。 新規クラスは、基底クラスから派生します。 新規クラスは、基底クラスの型のサブオブジェクト を含みます。 次の例は、継承メカニズムを使用してクラス B にクラス A のメンバーへのアクセスを 与える点を除いては、直前の例と同じです。
#include <iostream> using namespace std; class A { int data; public: void f(int arg) { data = arg; } int g() { return data; } }; class B : public A { }; int main() { B obj; obj.f(20); cout << obj.g() << endl; }
クラス A は、クラス B の基底クラスです。 クラス A のメンバーの名前、および定義は、クラス B の定義にインクルードされます。 つまり、クラス B は、クラス A のメンバーを継承します。 クラス B は、クラス A から派生します。 クラス B には、型 A のサブオブジェクトが含まれます。
派生クラスに新たにデータ・メンバーやメンバー関数を 追加することもできます。新たに派生させたクラスで基底クラスのメンバー関数やデータを オーバーライドすることによって、既存メンバー関数やデータの インプリメンテーションを変更することができます。
別の派生クラスからもクラスを派生できます。その結果、別のレベルの継承を作成します。 次の例は、このことを示しています。
struct A { }; struct B : A { }; struct C : B { };
クラス B は、A の派生クラスでもあり、 同時に、C の基底クラスでもあります。 継承のレベル数は、リソースによってのみ限定されます。
多重継承 を使用すると、 複数の基底クラスの属性を継承する派生クラスを作成することができます。 派生クラスは、その全基底クラスからメンバーを継承するので、 その結果あいまいさが生じる可能性があります。 例えば、2 つの基底クラスに同じ名前のメンバーがある場合、 派生クラスでは 2 つのメンバーを暗黙的に区別することができません。 多重継承を使用するときは、基底クラスの名前へのアクセスがあいまいにならないように注意してください。
直接基底クラス とは、その派生クラスの宣言の中に、 基底指定子として直接現れる基底クラスのことです。
間接基底クラス とは、派生クラスの宣言の中には直接出てこないが、 その基底クラスの 1 つを介して派生クラスで使用できる基底クラスのことです。 あるクラスについて、直接基底クラスでない基底クラスは、すべて間接基底クラスです。 次の例は、直接基底クラスおよび間接基底クラスを示しています。
class A { public: int x; }; class B : public A { public: int y; }; class C : public B { };
クラス B は、C の直接基底クラスです。 クラス A は、B の直接基底クラスです。 クラス A は、C の間接基底クラスです。 (x および y は、クラス C のデータ・メンバーになります。)
ポリモアフィック関数 は、複数の型のオブジェクトに適用できる関数です。 C++ では、ポリモアフィック関数は、2 つの方法でインプリメントできます。
関連参照