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 行目で削除にフラグを立てることを意味します。