Cの複数の継承により、クラスは複数の基本クラスから継承できます。これは、派生クラスがすべての親クラスのメンバー(データと関数)を取得できることを意味します。コンパイラは、すべてのベースクラスからのメンバー宣言を派生クラスに組み合わせます。ただし、この一見単純なメカニズムは、いくつかの複雑さをもたらします。
それがどのように機能するか:派生クラスが複数の基本クラスから継承すると、すべての公共および保護されたメンバー(コンストラクターと破壊者を除く。これらは継承されていないが、オブジェクトの作成と破壊中に呼び出されます)を継承します。名前の競合がある場合(2つの基本クラスには同じ名前のメンバーがあります)、コンパイラはこの曖昧さを解決する必要があります。この解像度は、スコープ解像度オペレーター(::)を使用して、どのベースクラスのメンバーが意図されているかを指定することで明示的に実行できます。たとえば、 BaseA
とBaseB
両方が関数foo()
を持っている場合、両方から導出された継承がDerived
場合、 Derived
由来はBaseA::foo()
またはBaseB::foo()
を使用して乱用する必要があります。
課題:
複数の継承の曖昧さを回避するには、慎重な計画とコーディングの実践が必要です。
process()
やdata()
などの汎用名は避けてください。代わりに、 processOrder()
やcustomerData()
などの記述名を使用します。BaseA::foo()
。「ダイヤモンドの問題」は、クラスが共通の祖先を共有する2つのクラスから継承すると発生します。仮想継承がなければ、共通の祖先は派生クラスのオブジェクトで複製され、データの不一致と潜在的なエラーにつながります。
仮想継承は、派生クラスのオブジェクトに共通の祖先の1つのインスタンスのみが存在することを保証することにより、これを解決します。これは、共通の祖先を中間クラスの仮想ベースクラスとして宣言することによって達成されます。
例:
<code class="c ">class Animal { public: int legs; }; class Mammal : virtual public Animal {}; class Bird : virtual public Animal {}; class Platypus : public Mammal, public Bird {};</code>
この例では、 Animal
Mammal
とBird
両方の仮想ベースクラスです。 Platypus
は、 Animal
のlegs
メンバーのインスタンスが1つしかなく、ダイヤモンドの問題を防ぎます。 virtual
キーワードがなければ、 Platypus
にはAnimal
のメンバーの2つのコピーがあります。
はい、いくつかの設計パターンは、複数の継承の代替品を提供します。
これらの代替案は、一般に、複数の継承よりもモジュール式で柔軟な、保守可能なコードにつながり、多くの場合cで望ましいものにします。彼らはより良いコード組織を促進し、複数の継承に関連する微妙なバグを導入するリスクを減らします。
以上が複数の継承はCでどのように機能し、その課題は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。