メインコンテンツ

AUTOSAR C++14 Rule A12-4-1

Destructor of a base class shall be public virtual, public override or protected non-virtual

説明

ルール定義

Destructor of a base class shall be public virtual, public override or protected non-virtual.

根拠

基底クラス デストラクターがパブリック バーチャルまたはパブリック オーバーライドでない場合は、クラスが派生クラス オブジェクトの削除に対してポリモーフィックに動作できません。

基底クラスへのポインターが派生クラス オブジェクトを参照し、ポインターを使用してオブジェクトを削除する場合は、次のようになります。

class Base {
  public:
    ~Base() {}
};
    
class Derived: public Base {
  public:
    ~Derived() {}
};
...
void func(Base* ptr) {
    //ptr might point to a Base or Derived object
    delete ptr;
}
基底クラス デストラクターのみが呼び出されます。派生クラスに割り当てられている追加リソースは解放されず、リソース リークの原因となることがあります。下の例を参照してください。

基底クラス ポインター経由の派生クラス デストラクターの呼び出しを回避するには、デストラクターを保護することによって意図を明示します。そうしなかった場合は、派生クラス オブジェクトのポリモーフィックな削除の可能性が考慮されなかったと見なされる可能性があります。

Polyspace 実装

チェッカーは、デストラクターがパブリック バーチャル、パブリック オーバーライド、または protected の非バーチャルではない基底クラスにフラグを設定します。

トラブルシューティング

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

すべて展開する

#include <new>

class Base {
  public:
    Base() {}
    ~Base() {} //Noncompliant
};
    
class Derived: public Base {
     int *arr;
  public:
     Derived() {
        arr = new int(5);
     }
    ~Derived() {
        delete arr;
     }
};

void main() {
    Base* basePtr = new Derived();
    delete basePtr;
}

この例では、クラス Base に非バーチャル デストラクターがあります。そのため、ポインター basePtr が削除されると、クラス Base のデストラクターのみが呼び出されます。ただし、basePtr は、クラス Derived のオブジェクトを指しています。削除は行われません。これは、クラス Derived のデストラクターが呼び出されないためです。具体的には、派生オブジェクト内のデータ メンバー arr が削除されません。

チェック情報

グループ: 特殊なメンバー関数
カテゴリ: Required、Automated

バージョン履歴

R2020a で導入