C ++の多重継承と菱形継承

他の多くのオブジェクト指向プログラミング言語とは異なり、C ++では多重継承が可能です。

多重継承により、子クラスは複数の親クラスから継承できます。

最初は、非常に便利な機能のようです。ただし、この機能を実装する際には、ユーザーはいくつかの落とし穴に注意する必要があります。

以下の例では、注意が必要ないくつかのシナリオについて説明します。

この概念をC ++で説明する簡単な例から始めます。

このコードの出力は次のとおりです。

I'm breathing as a snake.I’m crawling as a snake.

上記の例では、LivingThingという名前の基本クラスがあります。アニマルそして、爬虫類のクラスは、それを継承します。動物だけクラスはメソッドをオーバーライドしますbreathe()スネークからのクラス継承動物爬虫類のクラス。それは彼らのメソッドを上書きします。上記の例では、問題はありません。私たちのコードはうまく機能します。

ここで、少し複雑さを追加します。

Reptileクラスがbreathe()メソッドをオーバーライドした場合はどうなりますか?

スネーククラスは知っているだろうbreathe()に呼び出すメソッド。これが「菱形継承問題」です。

ダイヤモンド問題

以下のコードを見てください。Reptileクラスのbreathe()メソッドをオーバーライドしたことを除けば、上記の例のコードと似ています。

プログラムをコンパイルしようとしても、コンパイルできません。次のようなエラーメッセージが表示されます。

member ‘breathe’ found in multiple base classes of different types

このエラーは、多重継承の「菱形継承問題」が原因です。スネーククラスはわからないbreathe()呼び出すメソッド。

最初の例では、Animalクラスのみがオーバーライドされていました。breathe()方法。爬虫類のクラスがありませんでした。したがって、Snakeクラスがどのbreathe()メソッドを呼び出すかを理解することはそれほど難しくありませんでした。そして、Snakeクラスbreathe()Animalクラスのメソッドを呼び出すことになりました。

2番目の例では、Snakeクラスは2つのbreathe()メソッドを継承しています。動物爬虫類のクラスのbreathe()メソッド。Snakeクラスのメソッドをオーバーライドしていないため、あいまいさがあります。breathe()

C ++には、多重継承などの多くの強力な機能があります。ただし、提供されるすべての機能を使用する必要はありません。

私は多重継承を使用することを好みません、そして代わりに仮想継承を使用します

仮想継承は、古典的な「ダイヤモンド問題」を解決します。これにより、子クラスが共通基本クラスのインスタンスを1つだけ取得するようになります。

つまり、SnakeクラスにはLivingThingクラスのインスタンスが1つだけあります。動物爬虫類のクラスは、このインスタンスを共有します。

これにより、以前に受け取ったコンパイル時エラーが解決されます。抽象クラスから派生したクラスは、基本クラスで定義された純粋仮想関数をオーバーライドする必要があります。

この多重継承の概要と「菱形継承問題」を楽しんでいただけたでしょうか。