C+++虚構関数の使用分析
C++においては,虚構造関数を宣言することはできないが,虚構関数を宣言することができる。多形性とは、異なるオブジェクトが同じメッセージに対して異なる挙動特性を有することを意味する。虚関数は,動作時の多形性の基礎として,主にオブジェクトに対して,構造関数はオブジェクトの生成前に実行されるので,虚構造関数は意味がない。コンストラクタの機能は、このクラスのオブジェクトが滅亡する前に必要な清掃作業を行うもので、コンストラクタは、最も良いのはvirtualである。まず,虚構関数とポインタの間でどのように相互作用するか,および虚構関数の具体的な意味を説明する。例えば、SomeClassは非virtual構文関数を含むクラスです。SomeClass*p=new SomeClass; . . .delect p;pのためにdelectを呼び出すと、自動的にSomeClass類の構文関数が呼び出されます。これから、コンストラクションをvirtualと表記したら、何が起こるかを見てみます。解析関数と虚数関数機構の相互作用を記述する場合、最も簡単な表現は、すべての構文関数を同じ名前として扱うことである。例えば、Derived類はBase類の派生類であると仮定し、Base類の中の立体分析関数はvirtualとしてマークされる。以下のコードを分析します。Base*pBase=new Derived; . . .delect pBase;Baseのためにdelectを呼び出すと、構文関数を呼び出します。Baseクラスの中のコンストラクションはvirtualとしてマークされており、対象はDerivedタイプですので、Derivedクラスのコンフィギュレーション関数を呼び出します。注意すべき点は、コンストラクタをvirtualとしてマークした後、派生クラスのすべてのコンストラクタが自動的にvirtualとなります。同様に、このような行為は、すべての構文関数が同じ名前を持っているようです。以下はすべてのコンストラクションをvirtualとしてマークするメリットです。Baseクラスにはポインタタイプのメンバー変数pBがあると仮定し、Base類のコンストラクターはpBによる動的変数を作成し、Base類のコンストラクターはpB指向の動的変数を削除します。また、Baseクラスはvirtualとしてマークされていないと仮定し、Derived類は(Baseから派生した)ポインタタイプのメンバー変数pDがあると仮定し、Derived類の構造関数はpDが指す動的変数を作成し、Derived類の解析関数はpDが指す動的変化量を削除します。以下のコードを分析します。Base*pBase=new Derived; . . .delect pBase;基本クラスの中のコンストラクションはvirtualとしてマークされていないので、Baseクラスのコンストラクションのみが起動されます。pBが指すダイナミック変数のメモリは、自由に記憶されます。しかし、pDが指す動的変数にとって、占有メモリは、プログラムが終了しない限り、自由に記憶されない。一方、ベースBaseのコンストラクタがvirtualと表記されると、pBaseのためにdelectを呼び出すと、Derived類のコンストラクタが呼び出されます。Derived類の解析関数は、pD指向の動的変数を削除し、ベースベースベースベースベースベースの解析関数を自動的に呼び出します。後者はpB指向の動的変数を削除します。したがって、ベースのコンストラクタをvirtualとしてマークした後、すべてのメモリを自由に記憶して回収することができます。このような状況を迎えるためには、常にコンストラクションをvirtualと表記したほうがいいです。例を挙げて説明します。
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base(){cout << " Constructor in Base. " << endl;}
virtual ~Base(){ cout << " Destructor in Base. " << endl;}
};
class Derived:public Base
{
public:
Derived(){cout << " Constructor in Derived. " << endl;}
~Derived(){cout << "Destructor in Derived. " << endl;}
};
int _tmain(int argc, _TCHAR* argv[])
{
Base *p = new Derived;
delete p;
return 0;
}
出力: コンストラクターin Base. コンストラクターin Derived. Destoctor in Derived. デストローin Base. Baseの中のコンストラクションが、virtual修飾なしに出力された場合: コンストラクターin Base. コンストラクターin Derived. このようなDerivedの中のコンストラクターは実行されていないので、メモリが漏れてしまいます。したがって、他のクラスのベースクラスであれば、そのコンストラクタを虚構関数として宣言するべきです。また、この例からは、コンストラクタ、コンストラクタの実行順序が示されている。構造関数は、まず基質の後のサブクラス、コンストラクタ、先のサブクラス、後のベースクラスです。