next up previous
: 仮想関数と多態 : プログラミング演習 III その 3 : コンストラクタとデストラクタの継承

多重継承

クラスの継承は,多重に行うことができる. すなわち,あるクラスから派生したクラスを,さらに別の派生クラスが継承 することも可能である.

つまり,クラス A を基本クラスとして,それを 派生クラス B が継承し, さらに,クラス B を基本クラスとした派生クラス C を定義することが可能である.


class A {
...  // 基本クラス
};

class B: public A {
...  // クラス A の派生クラス
};

class C: public B {
...  // クラス B の派生クラス
};

また, クラス A を基本クラスとし,それぞれ異なる継承を行う派生クラス B と C を定義することもできる.


class A {
...  // 基本クラス
};

class B: public A {
...  // クラス A の派生クラス
};

class C: public A {
...  // クラス A の派生クラス
};

さらに, 複数の基本クラスの性質を引き継いだ 派生クラスを定義することも可能である.


class A {
...  // 基本クラス
};

class B {
...  // 別の基本クラス
};

class C: public A, public B {
...  // クラス A と クラス B の派生クラス
};

人口と面積を表す変数を公開メンバ変数として持つクラス prefecture があり,人口密度を返す公開関数 pop_density を持つとする. またクラス physique は 身長と体重を表す公開メンバ変数を持つクラスであるとする. 人口密度と身長や体重の関係を調べるため, 2 つのクラスから派生したクラス 同一の基本クラスから派生した異なるクラスを継承する場合を考える.


class prefecture {
   ...
 public:
   int population; /* 人口 */
   double area;    /* 面積 */
   double pop_density(void) /* 人口密度 */
     { return population / area; }
   ...
};

class physique {
  ...
public:
  double height;
  double weight;
  void set_height(double h) { height = h; }
  void set_weight(double w) { weight = w; }
  ...
};

class physique_and_pref: public prefecture, public physique {
public:
  ...
};
クラス physique_and_pref は, クラス prefecturephysique の両者からの派生クラスとなる.


int main()
{
  physique_and_pref pref[47];
  double dens[47];
  double ht[47];
  int i;

  for (i = 0; i < 47; i++) {
    dens[i] = pref[i].pop_density();
    ht[i] = prof[i].height;
  }
  ..
}
などとして,身長と人口密度の相関関係を調べることもできる.


ところで,次のようなクラスの定義を考える.


class prefecture {
public:
  char name[NAMELENGTH]; /* 県名 */
...
};
class pop: public prefecture { /* prefecture の派生クラス */
public:
  int population;
  ...
};

class area: public prefecture { /* prefecture の派生クラス */
public:
  float s;
...
};

class pop_density: public pop, public area {
  ...
};

このとき, クラス prefecture は, クラス pop_density の基本クラスである poparea の共通する基本クラスである. このため,pop_density には,prefecture のコピーが 2 つ存在することになり,曖昧になる. このようなときは, 仮想基本クラスとし,基本クラスのコピーを複数含まないようにする. その指定方法は,以下に示すように,基本クラスアクセス指定子の前に virtual を指定する.


class prefecture {
public:
  char name[NAMELENGTH]; /* 県名 */
...
};
class pop: virtual public prefecture { /* prefecture の派生クラス */
public:
  int population;
  ...
};

class area: virtual public prefecture { /* prefecture の派生クラス */
public:
  float s;
...
};

class pop_density: public pop, public area {
  ...
};



Takeshi Kumagai 平成19年6月19日