multiple inheritance。
1つの派生クラスが、複数の基底クラスを同時に継承すること。
基本構文
class Teacher : public Person, public Employee
{
};このように、基底クラスをカンマ区切りで複数指定する。
例
class Person
{
};
class Employee
{
};
class Teacher : public Person, public Employee
{
};この例では、TeacherはPersonでもあり、Employeeでもある。
ミックスイン
多重継承は、小さな機能追加用クラスを組み合わせるためにも使われる。
このような小さな基底クラスは、ミックスインと呼ばれることがある。
問題点
同名メンバの曖昧さ
複数の基底クラスが同じ名前のメンバ関数を持つと、どれを呼ぶべきか曖昧になることがある。
class USBDevice
{
public:
long getID() const
{
return 0;
}
};
class NetworkDevice
{
public:
long getID() const
{
return 1;
}
};
class WirelessAdapter : public USBDevice, public NetworkDevice
{
};このとき、WirelessAdapterのオブジェクトに対してgetID()をそのまま呼ぶと、どちらのgetID()か決められずコンパイルエラーになる。
必要なら、USBDevice::getID()のようにスコープ解決演算子で明示する。
菱形継承問題
あるクラスを、共通の基底クラスを持つ2つのクラスからさらに多重継承すると、ダイヤモンド型の継承関係になることがある。
class PoweredDevice
{
};
class Scanner : public PoweredDevice
{
};
class Printer : public PoweredDevice
{
};
class Copier : public Scanner, public Printer
{
};このような場合、CopierがPoweredDeviceを1つ持つべきか2つ持つべきか、共通基底クラスのメンバ参照をどう扱うか、といった問題が生じる。
注意
- 多重継承は便利なこともあるが、名前の衝突や保守性の低下を招きやすい
- 特に菱形継承問題は複雑さの大きな原因になる
- コンポジションや単一継承で、多重継承を使う理由を解決できる場合が多いので、そちらを優先すべき