多重継承の概要

これは,C++プログラマであるかを見分ける10の質問 - Life like a clown の 「多重継承について概要を説明せよ」と言う質問に対する回答的な記事です.多重継承とは,その名の通り,以下のように 2 つ以上のクラスを継承する事を指します.

class Base1 {
public:
    virtual ~Base1() {}
    virtual void do_something1();
};

class Base2 {
public:
    virtual ~Base2() {}
    virtual void do_something2();
};

class Derived : public Base1, public Base2 {
    ...
};

一般的に多重継承になりやすいケースは,インターフェースや Mix-in と言った使い方をする場合でしょうか.Mix-in で一番よく使いそうな例だと Non-copyable Mixin 辺りかなと思います.「何らかのクラスを継承したクラスを作成したいんだけど non-copyable にしたい」と言ったケースでは多重継承はよく目にします.

多重継承で気をつけなければいけないのはダイヤモンド継承と呼ばれる問題です.あるクラスが継承した 2つ(以上)のクラスが,ある一つの基底クラスを継承していた場合,同じメンバ変数やメンバ関数(メソッド)が複数存在する事になるので,どの基底クラスのメンバー変数/関数を使うか曖昧さが残る事になります.これを仮想継承と言い,以下のように virtual キーワードを付与します.

class Base {
public:
    virtual ~Base() {}
    virtual void do_something();
    int foo;
};

class Derived1 : public virtual Base { // 仮想継承
public:
    virtual ~Derived1() {}
};

class Derived2 : public virtual Base { // 仮想継承
public:
    virtual ~Derived2() {}
};

class NestedDerived : public Derived1, public Derived2 {
    ...
};

多重継承は複雑になりがち,と言う理由で嫌う人もいるようです.多重継承を回避する方法としては,例えばインターフェースのような使い方だと,ポリシー・ベース(テンプレート・パラメータでインターフェース的なクラスを指定するようにする)でもある程度は代替できそうです.「多重継承だから禁止」のような方針はあまり良いとは思いませんが,まぁ各人が良いと思う形でクラス設計できれば良いのではないかと思います.