バーチャル継承の欠落
基底クラスが同じ階層内でバーチャルに継承され、また非バーチャルに継承されている
説明
この欠陥は、以下の場合に発生します。
あるクラスが複数の基底クラスから派生しており、その基底クラスの一部はそれ自体が共通の基底クラスから派生している。
たとえば、クラス
Finalが 2 つのクラス、Intermediate_leftおよびIntermediate_rightから派生しており、Intermediate_leftとIntermediate_rightのいずれも、共通のクラスBaseから派生している場合などです。共通の基底クラスからの継承のうち少なくとも 1 つが
virtualであり、少なくとも 1 つがvirtualではない。たとえば、
BaseからのIntermediate_rightの継承がvirtualであり、BaseからのIntermediate_leftの継承はvirtualではない場合などです。
リスク
この欠陥が発生すると、基底クラスのデータ メンバーのコピーが、最終的な派生クラス オブジェクトに複数出現します。基底クラスのデータ メンバーの正しいコピーにアクセスするため、最終的な派生クラスでは、メンバーとメソッド名を適正に修飾する必要があります。そのため、開発でエラーが発生しやすくなります。
たとえば、この欠陥が発生すると、基底クラスのデータ メンバーのコピーが、クラス Final のオブジェクトに 2 つ現れます。クラス Final でメソッド名を適正に修飾しない場合、値を Base のデータ メンバーに代入できても、同じ値を取得することはできません。
値の代入には、
Intermediate_left経由でアクセスするBaseメソッドを使用します。したがって、値はBaseメンバーの一方のコピーに代入されます。値の取得には、
Intermediate_right経由でアクセスするBaseメソッドを使用します。したがって、Baseメンバーの別のコピーが取得されることになります。
修正方法
あるクラスが、それ自体が共通の基底クラスから派生している複数の基底クラスから派生している場合、すべての中間継承を virtual として宣言します。
中間派生クラスで表されるような Base データ メンバーのコピーが実際に複数必要である場合は、継承の代わりに集約を使用します。たとえば、Final クラス内でクラス Intermediate_left と Intermediate_right の 2 つのオブジェクトを宣言します。
例
結果情報
| グループ: オブジェクト指向 |
| 言語: C++ |
| 既定値: オフ |
コマンド ライン構文: MISSING_VIRTUAL_INHERITANCE |
| 影響度: Medium |
バージョン履歴
R2015b で導入