基本クラスの非仮想デストラクター

仮想メンバー関数を含む C++ クラスに非仮想デストラクターがあります。

この関数には仮想メンバー関数が含まれているため、基本クラスとして使用されます。基本クラスでの非仮想デストラクターの使用は、オブジェクトが正しく破棄されない可能性があるため危険です。以下にこの問題の例を示します。

基本クラスのデストラクターとして適切なのは、public または protected 仮想デストラクターのみです。protected 非仮想デストラクターは、public 非仮想デストラクターと同じように問題があります。この 2 つの違いは、派生クラスのメンバー関数内だけで問題が発生するかどうかです。

デストラクターを protected にすると、そのクラスのインスタンスを削除できなくなります。これは、参照カウントなどによって存続時間を制御するオブジェクトを実装する場合に役立ちます。それ以外の場合では、public 仮想デストラクターを使用してください。

ID

問題箇所

説明

1

定義

クラスが定義された場所

          
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

class evil {
public:
    ~evil() {} // bad: should be virtual
    virtual void say_hi() { printf("I am evil\n"); }
};

// class with a non-trivial destructor
class victim : public evil {
protected:
    char * m_string;
public:
    victim() { m_string = new char[40]; }
    ~victim() { delete m_string; }

    // copy constructor
    victim::victim(const victim & source)
      : m_string(new char[40])
    {
        for (int i = 0; i < 40; i++) {
            m_string[i] = source.m_string[i];
        }
    }

    // assignment operator
    victim& victim::operator=(const victim & source)
    {
        for (int i = 0; i < 40; i++) {
            m_string[i] = source.m_string[i];
        }
        return *this;
    }

};

int main(int argc, char **argv)
{
    evil* p = new victim(); // allocates m_string
    p->say_hi();
    delete p;
    // Calls ~evil, but not ~victim because ~evil is not virtual
    // therefore m_string is never freed
};
        

© 2010 Intel Corporation. 無断での引用、転載を禁じます。