C++のダミー構造関数


class A
{
public:
    A(){}
    virtual ~A(){} //              delete p;      ~A(),          ,m_data      
};

class B : public A
{
public:
    char* m_data;
    B() { m_data = new char[100]; }
    ~B() { delete m_data; }
};

int main(int argc, char **argv)
{
    A *p = new B;
    delete p; //         free  
    return 0;
}


仮想構造関数は、ベースクラスのポインタが派生クラスオブジェクトを指し、ベースクラスのポインタで派生クラスオブジェクトを削除するという問題を解決するためです.クラスに虚関数が含まれていない場合は、一般的にベースクラスとして使用されないことを示します.クラスがベースクラスとして使用する準備ができていない場合、構造関数を虚にするのは一般的に悪い考えです.クラスに虚関数テーブルを追加するため、オブジェクトのボリュームが2倍になり、移植性が低下する可能性があります.だから基本的な1つは、理由もなく虚析構関数を宣言することは、永遠に宣言しないのと同じように間違っています.実際、多くの人は、クラスに少なくとも1つの虚関数が含まれている場合にのみ、虚解析関数を宣言するとまとめています.抽象クラスはベースクラスとして使用される準備ができており、ベースクラスには虚析構造関数が必要であり、純虚関数は抽象クラスを生成するので、方法は簡単です.抽象クラスになりたいクラスに純虚析構造関数を宣言します.
#include <stdio.h>

class Base 
{
    public:
        virtual ~Base() = 0;
};

Base::~Base() { printf("..
"); } // class A : public Base { }; int main() { A a; return 0; }

  
このクラスには純粋な虚関数があるので抽象的であり、虚構造関数があるので、構造関数の問題は発生しません.しかし、ここでもう一つのことは、純粋な虚構造関数の定義を提供する必要があります:Base::~Base(){printf(".");}定義しなければなりません.この定義は、最下位の派生クラスの構造関数が最初に呼び出され、各ベースクラスの構造関数が呼び出されるため、虚構造関数が動作する方法が必要です.すなわち,コンパイラは抽象クラスでも~Baseへの呼び出しを生成するので,関数体を提供することを保証する.そうしないとリンクが検出され、最後には戻って追加しなければなりません.注意:仮想構造関数をinlineと宣言すると、呼び出し時に発生するオーバーヘッドは回避されますが、コンパイラは必ずこの関数のコピーをどこで生成しますか.