このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
オブジェクトのスライス
派生クラス オブジェクトが基底クラス パラメーターをもつ関数に値渡しされる
説明
この欠陥は、派生クラス オブジェクトを関数に値で渡したが、その関数がパラメーターとして基底クラス オブジェクトを予期していた場合に発生します。
リスク
派生クラス オブジェクトを関数に "値渡し" する場合は、派生クラスのコピー コンストラクターが呼び出されるものと想定されます。関数で必要とされるのがパラメーターとしての基底クラス オブジェクトであった場合、
基底クラスのコピー コンストラクターが呼び出されます。
関数本体で、パラメーターは基底クラス オブジェクトとみなされます。
C++ では、クラスの virtual
メソッドがオブジェクトの実際のタイプに応じて実行時に解決されます。オブジェクトのスライスのため、virtual
メソッドの不適切な実装が呼び出される場合があります。たとえば、基底クラスには virtual
メソッドが含まれ、派生クラスにはそのメソッドの実装が含まれているとします。virtual
メソッドを関数本体から呼び出すと、関数に派生クラスのオブジェクトを渡しても、基底クラスのメソッドが呼び出されます。
修正方法
1 つの修正方法として、オブジェクトを参照かポインターで渡します。参照かポインターで渡せば、コピー コンストラクターの呼び出しは発生しません。オブジェクトが変更されないようにするには、関数パラメーターに const
修飾子を使用します。
別の修正方法として、関数を、派生クラス オブジェクトをパラメーターとして受け取る別の関数でオーバーロードします。
例
結果情報
グループ: オブジェクト指向 |
言語: C++ |
既定値: 手書きコードはオン、生成コードはオフ |
コマンド ライン構文: OBJECT_SLICING |
影響度: High |
バージョン履歴
R2015b で導入