AUTOSAR C++14 Rule A10-3-5
A user-defined assignment operator shall not be virtual
説明
ルール定義
ユーザー定義の代入演算子はバーチャルにしないものとします。
根拠
基底クラスで代入演算子を virtual として定義すると、それを派生クラスでオーバーライドすることになります。派生クラスで代入演算子をオーバーライドすると、未定義の動作やランタイム エラーにつながる可能性があります。バーチャル代入演算子が 2 つの派生クラスでオーバーライドされる次のコード スニペットを考えてみましょう。
class Base {public:
virtual Base& operator=(Base const& oth) = 0;
//...
};
class Derived public: Base{ public:
Derived& operator=(Base const& oth) override{/*...*/}
//...
};
class Derived2 public: Base{public:
Derived2& operator=(Base const& oth) override{/*...*/}
//...
};
main(){
Derived d1;
Derived2 d2;
d1 = d2;
}Derived::operator= と Derived2::operator= が Base::operator= をオーバーライドするため、これらのパラメーター リストを同じにする必要があります。
Derived::operator=は、Baseオブジェクトへの参照を入力として取得し、Derivedへの参照を返します。Derived2::operator=は、Baseオブジェクトへの参照を入力として取得し、Derived2への参照を返します。
Derived::operator= は、Base クラス オブジェクトと Derived クラス オブジェクトの両方への参照を受け入れます。これは、派生クラスへの参照がそれらの基底クラスと型互換性があるためです。同様に、Derived2::operator= も、Base クラス オブジェクトと Derived2 クラス オブジェクトの両方への参照を受け入れます。d1=d2 で Derived オブジェクトを Derived2 オブジェクトに代入しても、コンパイル エラーは発生しません。オブジェクトの d1 と d2 は無関係です。このような無関係のオブジェクト間の代入操作、コピー操作、または移動操作は、未定義であり、ランタイム エラーにつながる可能性があります。
未定義の動作とランタイム エラーを回避するには、ユーザー定義の代入演算子を非バーチャルのままにします。このルールは以下の演算子に適用されます。
代入
コピー代入と移動代入
すべての複合代入
Polyspace 実装
Polyspace® は、基底クラス内のすべてのバーチャル代入演算子の宣言にフラグを設定します。
トラブルシューティング
ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
| グループ: 派生クラス |
| カテゴリ: Required、Automated |
バージョン履歴
R2020a で導入