メインコンテンツ

AUTOSAR C++14 Rule A10-3-1

Virtual function declaration shall contain exactly one of the three specifiers:(1) virtual, (2) override, (3) final

説明

ルール定義

Virtual function declaration shall contain exactly one of the three specifiers:(1) virtual, (2) override, (3) final.

根拠

バーチャル関数は、クラス階層にポリモーフィックな動作を実装します。基底クラスで関数を virtual として宣言すると、派生クラス内に同じパラメーター リストをもつすべての関数のインスタンスによって基底関数が暗黙的にオーバーライドされます。ポリモーフィックな関数の実装をコンパイラによるこの暗黙的アクションに依存している場合は、エラーにつながる可能性があります。次に例を示します。

  • 関数が誤って virtual になる可能性があります。これは、その署名が基底クラス内のバーチャル関数と一致するためです。

  • 関数が誤って非バーチャルになる可能性があります。これは、パラメーター リストに違いがあるためです。

バーチャル関数を暗黙的に宣言すると、コードが読みにくくなる可能性もあります。

不注意によるエラーを回避し、可読性を向上させるには、指定子の virtualoverride、または final を使用して、バーチャル関数またはオーバーライドする関数を明示的に定義します。1 つの宣言内でこれらの指定子を 2 つ以上使用すると、冗長になったり、エラーの原因になるため、これらの指定子は必ず 1 つだけ使用します。

  • 新しいバーチャル関数を宣言する場合は virtual のみ。

  • バーチャル関数の非最終のオーバーライドする関数を宣言する場合は override のみ。

  • バーチャル関数の最終のオーバーライドする関数を宣言する場合は final のみ。

Polyspace 実装

Polyspace® は、以下の場合にバーチャル関数の宣言にフラグを設定します。

  • 宣言でどの指定子も使用されていない。

  • 宣言で 2 つ以上の指定子が使用されている。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include<cstdint>
class Base
{
public:
	virtual void F() noexcept = 0;                 // Compliant
	virtual void G() noexcept final = 0;           // Noncompliant
	virtual void H() noexcept final {}             // Noncompliant
	virtual void J() noexcept {}                   // Compliant
	virtual void K() noexcept {}                   // Compliant
	virtual ~Base() {}                             // Compliant
	virtual void M() noexcept {}                   // Compliant
	virtual void Z() noexcept {}                   // Compliant
	virtual void X() throw() {}                    // Compliant
	virtual void Y() noexcept {}                   // Compliant
};                                                 

class Derived : public Base                        
{                                                  
public:                                          
	~Derived() {}                                  // Noncompliant
	virtual void F() noexcept override {}          // Noncompliant
	void K() noexcept override final {}            // Noncompliant
	virtual void M() noexcept {}                   // Compliant
	void Z() noexcept override {}                  // Compliant
	void J() noexcept {}                           // Noncompliant
	void J(int) noexcept {}                        // Compliant
	virtual void X() throw() final {}              // Noncompliant
	virtual void Y() noexcept override final {}    // Noncompliant
};
class DD: public Derived{
//	void J(int) noexcept override{}       //Compilation error
};
main(){
	//...
}

  • 派生クラス ~Derived() のデストラクターがバーチャル関数です。その宣言は、バーチャル関数の 3 つの指定子のいずれも含まれていないため、このルールに違反します。

  • 純粋なバーチャル関数 Base::G() の宣言も、virtualfinal の両方が指定子として含まれているため、このルールに違反します。final としても指定された純粋なバーチャル関数は冗長です。

  • バーチャル関数 Derived::J() の宣言は、Derived::J() が指定子 override を使用せずにバーチャル関数 Base::J() を暗黙的にオーバーライドするため、このルールに違反します。

  • バーチャル関数の Derived::X()Derived::Y() の宣言は、複数の指定子が使用されているため、このルールに違反します。

関数 DD::J(int) の宣言は、DD::J(int)Derived::J(int) をオーバーライドしようとしているため、コンパイル エラーを引き起こします。Derived::J(int) の署名が Base::J() の署名と異なるため (おそらく間違って)、Derived::J(int) はバーチャル関数ではなくなります。Derived::J(int)DD::J(int) でオーバーライドしようとすると、コンパイル エラーになります。バーチャル関数の宣言で指定子を 1 つだけ使用することによって、エラーの検出が容易になります。

チェック情報

グループ: 派生クラス
カテゴリ: Required、Automated

バージョン履歴

R2020a で導入