解析C++の中の虚析构関数の役割
C+++を用いて開発したとき,ベースクラスを作るために用いられた解析関数は一般的に虚関数であることを知っている。しかし、なぜこのようにしますか?以下は小さな例で説明します。 次の2つのクラスがあります。
class ClxBase
{
public:
ClxBase() {};
virtual ~ClxBase() {};
virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};
class ClxDerived : public ClxBase
{
public:
ClxDerived() {};
~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };
void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
コード
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
の出力結果は、Do something in class CxDerivedです。Output from the destructor of class CxDerived!これは簡単で、よく分かります。しかし、クラスCxBaseのコンストラクタの前のvirtualを取り除くと、その出力結果は次のようになります。Do something in class CxDerived!つまり、クラスCxDerivedのコンストラクションはまったく呼び出されていません。一般的にはクラスのコンストラクションの中にはメモリ資源を放出しますが、コンストラクションが呼び出されないとメモリが漏れます。すべてのC++プログラマーがこのような危険性を知っていると思います。もちろん、コンストラクタで他の仕事をしたら、あなたの努力は全部無駄です。だから、冒頭の問題の答えは、つまり、派生クラスのオブジェクトを一つのベースクラスのポインタで削除するときに、派生クラスのコンストラクションが呼び出されるためです。もちろん、すべての種類の構文関数を虚関数と書くわけではありません。クラスの中に虚関数がある場合、コンパイラはクラスに虚関数テーブルを追加します。中には虚関数の針を保存します。そうすると、クラスの記憶空間が増加します。したがって、一つのクラスがベースとして使われるときにのみ、構文関数を虚関数として書くことができる。