多重継承
より複雑な継承
継承は一段階にとどまりません
ある基本クラスから派生したクラスを基本クラスとして
さらにそこから派生クラスを生成するといった多段階継承が可能です
串のように、断層的に継承した場合、コンストラクタはもっとも最下層の基本クラスから実行され
デストラクタはその逆、最終的な派生クラスのものから実行されます
このとき、派生クラスの基本クラスが継承している基本クラスを間接基本クラスと呼びます
上の図は派生クラスから見た関係図です
派生クラスは上の二つのクラスの機能を全て継承しています
#include<iostream>
using namespace std;
class Neko {
public:
Neko() { cout << "A house cat\n"; }
};
class Kitty : public Neko {
public:
Kitty() { cout << "Kitty on your lap\n"; }
};
class Zoo : public Kitty {
public:
Zoo() { cout << "Nekoneko Zoo\n"; }
} obj ;
int main() {
return 0;
}
結果は次のようになりました
A house cat
Kitty on your lap
Nekoneko Zoo
コンストラクタが、最初の基本クラスから開始していることがわかります
上のプログラムはコンストラクタの実験のみですが、派生クラス Zoo は
Kitty と Neko クラスの公開メンバ(及び破保護)を継承します
上の場合は直列的継承ですが
一つの派生クラスが複数の基本クラスを持つ並列的継承も可能です
このような、一つのクラスが複数のクラスを継承することを多重継承と呼びます
派生クラスは二つの基本クラスの機能を同時に継承します
この場合、継承する時の構文は次のように記述します
class derived : type base1 , type base2 , ... {
typeにはアクセス指定子を指定します
この場合、コンストラクタは左の基本クラスから順に実行されます
上の場合、base1 , base2 , derived の順でコンストラクタが実行されます
デストラクタは、これの逆の順番で実行されます
#include<iostream>
using namespace std;
class Neko {
public:
Neko() { cout << "A house cat\n"; }
};
class Kitty {
public:
Kitty() { cout << "Kitty on your lap\n"; }
};
class Zoo : public Kitty , public Neko {
public:
Zoo() { cout << "Nekoneko Zoo\n"; }
} obj ;
int main() {
return 0;
}
これを実行すると、次のようになりました
Kitty on your lap
A house cat
Nekoneko Zoo
基本クラスの指定順でコンストラクタが実行されています
また、派生クラスから基本クラスのコンストラクタに引数を渡すには
派生クラスのコンストラクタで次のような構文を使用します
derived(arg) : base1(arg) , base2(arg) , ... {
argは引数リストです
これも、派生クラスから基本クラスのコンストラクタ呼び出しさえ理解していれば問題ないですね
引数を渡したいコンストラクタが複数あれば、カンマで区切って渡すだけです
#include<iostream>
using namespace std;
class Neko {
public:
Neko(char *str) { cout << str; }
};
class Kitty {
public:
Kitty(char *str) { cout << str; }
};
class Zoo : public Kitty , public Neko {
public:
Zoo(char *base1 , char *base2) : Kitty(base1) , Neko(base2) {
cout << "Nekoneko Zoo\n";
}
} obj("Kitty on your lap\n" , "A house cat\n") ;
int main() {
return 0;
}
このプログラムでは、基本クラスのコンストラクタに
派生クラスのコンストラクタから引数を渡しています