CWARN.DTOR.NONVIRT.NOTEMPTY

クラスでは仮想関数が継承されますが、デストラクタは仮想ではなく、空ではありません

CWARN.DTOR.NONVIRT.NOTEMPTY チェッカーは、クラスで、その基本クラスから継承される仮想メンバー関数を宣言するが、デストラクタは仮想ではなく、空でもないクラスにフラグを立てます。

脆弱性とリスク

基本クラスから派生したクラスのオブジェクトを、その基本クラスを指すポインターを介して削除する場合、その派生クラスのデストラクタは実行されません。そして、その派生クラスのメンバーは適切に破棄されません。このような状況により、メモリのリークやリソースが解放されないといった問題につながる可能性があります。

軽減と防止

仮想メソッドと、暗黙的または明示的に適切に破棄する必要のあるメンバーデータを含むクラスに仮想デストラクタ (空であっても) を用意することが重要です。派生クラスは、基本クラスから継承します。基本クラスのデストラクタが仮想として定義されていない場合、メモリは適切に割り当て解除されません。仮想関数を宣言する、またはオーバーライドするクラスの階層では、仮想デストラクタは、その階層のルートクラスに対して 1 回だけ定義する必要があります。

脆弱コード例

コピー
   #include <iostream>
   using namespace std; 
    
   class A
   {
   public
    
       ~A() {std::cout << "I am A" << std::endl;}
       virtual void f1();
  };
   
  class B : public A
  {
  public
   
      ~B() {cout << "I am B" << endl;} 
      virtual void f1();
  };

このコード例で、クラス A に仮想デストラクタがないということは、Klocwork が 16 行目で削除にフラグを立てることを意味します。