トップ-> C++入門:6章 継承-> 仮想デストラクタ

←前ページへ :  トップへ :  次ページへ→

9. 仮想デストラクタ

  派生クラスを作成した場合、コンストラクタは、基底クラスのコンストラクタ、 派生クラスのコンストラクタの順に呼ばれることは前述 の通りである。

  そしてデストラクタは、派生クラスのデストラクタ、基底クラスのデストラクタの 順に呼ばれることも述べた

  しかし、デストラクタが仮想でないと、基底クラスポインタに、派生クラスのインスタンスの ポインタが代入されている場合、deleteしても、それは静的結合に よってデストラクタが呼ばれるため、基底クラスのデストラクタしか呼ばれない。

  下の例では、デストラクタが非仮想の場合と仮想の場合を比較した。基底クラスのポインタに 派生クラスをnewして、deleteしたときに違いが現れることを示している。

非仮想デストラクタ仮想デストラクタ
// 親クラス
class Base{
public:
    Base(){
        cout << "Base::Base()" << endl;
    }
    ~Base(){
        cout << "Base::~Base()" << endl;
    }
};

// 子クラス
class Deriv : public Base{
public:
    Deriv(){
        cout << "Deriv::Deriv()" << endl;
    }
    ~Deriv(){
        cout << "Deriv::~Deriv()" << endl;
    }
};

void main(){
    {
        Deriv deriv;
    }
    cout << endl;

    Base*  pBase;
    Deriv* pDeriv;

    pBase = new Base();
    delete pBase;

    cout << endl;

    pBase = new Deriv();
    delete pBase;

    cout << endl;

    pDeriv = new Deriv();
    delete pDeriv;
}
// 親クラス
class Base{
public:
    Base(){
        cout << "Base::Base()" << endl;
    }
    virtual ~Base(){
        cout << "Base::~Base()" << endl;
    }
};

// 子クラス
class Deriv : public Base{
public:
    Deriv(){
        cout << "Deriv::Deriv()" << endl;
    }
    virtual ~Deriv(){
        cout << "Deriv::~Deriv()" << endl;
    }
};

void main(){
    {
        Deriv deriv;
    }
    cout << endl;

    Base*  pBase;
    Deriv* pDeriv;

    pBase = new Base();
    delete pBase;

    cout << endl;

    pBase = new Deriv();
    delete pBase;

    cout << endl;

    pDeriv = new Deriv();
    delete pDeriv;
}
Base::Base()
Deriv::Deriv()
Deriv::Deriv()
Base::Base()

Base::Base()
Base::Base()

Base::Base()
Deriv::Deriv()
Base::Base()

Base::Base()
Deriv::Deriv()
Deriv::Deriv()
Base::Base()

Base::Base()
Deriv::Deriv()
Deriv::~Deriv()
Base::~Base()

Base::Base()
Base::~Base()

Base::Base()
Deriv::Deriv()
Deriv::~Deriv()
Base::~Base()

Base::Base()
Deriv::Deriv()
Deriv::~Deriv()
Base::~Base()

  このように派生クラスのインスタンスを作っているにもかかわらず、派生クラスのデストラクタが 呼ばれないのは問題がある。したがって、今後、クラスが派生される可能性が少しでもあるばらば、 デストラクタは仮想とするべきである。



←前ページへ :  トップへ :  次ページへ→