多重継承は、ひし形クラスと長方形クラスの両方の特徴を継承した正方形クラスのような
ものを言います。しかし四角形クラスから派生したひし形クラスと長方形クラスを多重継承して
正方形クラスを作るようなことはあまりありません。つまり1つの系列から派生した複数の
クラスを多重継承することはあまりありません。
多重継承はどのような使い方をするかといいますと、種類で派生した系列があります。
それとは全く関係なく機能で派生した系列があります。この2つを多重継承して、
1つの具象クラスを作るような場合です。
例えば上図のように、種類の継承系列として、哺乳類クラスを継承して犬クラスや
猫クラスなどがあります。またそれとは別の系列として、機能クラスを継承して、
救助クラスや盲導クラスなどがあります。盲導犬クラスを作る場合は、盲導クラスと
犬クラスを多重継承して作ります。麻薬捜査犬クラスを作る場合は、犬クラスと麻薬捜査
クラスを多重継承します。
もうひとつの使い方として、インターフェースとして使う場合があります。
おそらくこの方法が一番多く使われる方法です。
インターフェースとは、上の例と似ていますが、機能を司るクラスのことを言います。
もう少し具体的に言うと、インターフェースは抽象クラスで、それを派生したクラスでは
絶対に実装してほしい関数を純粋仮想関数として定義します。
上図はインターフェースの例です。基底クラスとしてダイアログクラスがあり、何かの
計算結果を表示するための結果表示ダイアログクラスはダイアログクラスを継承しています。
それとは別にインターフェースクラスがあり、これは純粋仮想関数として、更新という
関数が定義されています。つまりインタフェースクラスは抽象クラスです。そして
インターフェースクラスと結果表示ダイアログを多重継承して、途中結果表示ダイアログ
を作っています。
また、Windowsでファイルコピーやアプリケーションのインストールの時にどのくらい
進んだかを表示するプログレスバーというのがありますが、それを表示するプログレスバー
クラスとインターフェースを多重継承して、進行状況表示プログレスバークラスを定義しています。
何かを計算しているときに、更新関数を呼びますが、これをC++で実装すると以下のように
なります。
// ダイアログクラス
class Dialog{
public:
Dialog();
virtual ~Dialog();
virtual void Show();
virtual void Init();
};
// プログレスバークラス
class ProgressBar{
public:
ProgressBar();
virtual ~ProgressBar();
virtual void Show();
virtual void Init();
};
// インターフェースクラス
class Interface{
public:
virtual void Renew() = 0;
};
// 結果表示ダイアログクラス
class ShowResultDialog : public Dialog{
public:
ShowResultDialog() : Dialog();
virtual ~ShowResultDialog();
virtual void Show();
virtual void Init();
};
// 途中結果表示ダイアログクラス
class ShowHalfwayResultDialog : public Dialog, public Interface{
public:
ShowHalfwayResultDialog() : Dialog();
virtual ~ShowHalfwayResultDialog();
virtual void Show();
virtual void Init();
virtual void Renew();
};
// 進行状況表示プログレスバークラス
class ShowProgressBar : public ProgressBar, public Interface{
public:
ShowProgressBar() : ProgressBar();
virtual ~ShowProgressBar();
virtual void Show();
virtual void Init();
virtual void Renew();
};
// 計算関数
// pInterface 進行状況を通知するクラスの配列
// n 進行状況を通知するクラスの配列の要素数
void Calculation(Interface* pInterface[], int n){
for( int i = 0 ; i < 1000 ; i++ ){
:
:
// 進行状況を通知
for( int j = 0 ; j < n ; j++ )
pInterface[j]->Renew();
}
}
// メイン
void main(){
ShowHalfwayResultDialog dlg;
ShowProgressBar bar;
Interface* pInterface[2];
pInterface[0] = &dlg;
pInterface[1] = &bar;
// 計算
Calculation( pInterface, sizeof(pInterface) / sizeof(Interface*) );
ShowResultDialog ResultDialog;
ResultDialog.Show();
}
|