コンストラクターとデストラクターの概要

C++データや関数を含むクラスの内部構造は複雑なので、 オブジェクトの初期化やクラス終結処理は、単純なデータ構造の場合より格段に複雑です。 コンストラクターやデストラクターは、クラス・オブジェクトの構成や 破棄に使用されるクラスの特殊なメンバー関数です。構成では、オブジェクトのメモリー割り振りや初期化もあわせて 行われる場合があります。破棄に際しては、オブジェクトのメモリーの終結処理や割り振り解除も 行われる場合があります。

他のメンバー関数と同様、コンストラクターとデストラクターは、クラス宣言の中で宣言されます。 これらは、インラインまたはクラス宣言の外で定義することができます。 コンストラクターは、デフォルトの引き数を持つことができます。 コンストラクターは、他のメンバー関数と異なり、メンバー初期化リストを持つことができます。 コンストラクターとデストラクターには、次の制約事項が適用されます。

コンストラクターとデストラクターは、メンバー関数と同じアクセス規則に従います。 例えば、protected を使用してコンストラクターを宣言した場合、 それを使用してクラス・オブジェクトを使用できるのは、派生クラスとフレンドだけです。

コンパイラーは、クラス・オブジェクトを定義するときはコンストラクターを、 クラス・オブジェクトがスコープ外に出るときはデストラクターを、それぞれ自動的に呼び出します。 コンストラクターは、その this ポインターが参照するクラス・オブジェクトに、 メモリーを割り振ることはありませんが、 そのクラス・オブジェクトが参照するオブジェクトより多くのオブジェクトに、ストレージを割り振る場合があります。 オブジェクトのためにメモリー割り振りが必要な場合、 コンストラクターは、明示的に new 演算子を呼び出します。 終結処理時に、デストラクターは、 対応するコンストラクターによって割り振られたオブジェクトを解放します。 オブジェクトを解放するには、delete 演算子を使用します。

派生クラスはその基底クラスのコンストラクターやデストラクターを継承しませんが、 基底クラスのコンストラクターやデストラクターを呼び出します。 デストラクターは、virtual というキーワードで宣言できます。

コンストラクターは、ローカルまたは一時クラス・オブジェクトが作成されるときにも呼び出され、 デストラクターは、ローカルまたは 一時オブジェクトがスコープを超えたときに呼び出されます。

コンストラクターまたはデストラクターから、メンバー関数を呼び出すことができます。 クラス A のコンストラクター、またはデストラクターから、 直接的に、あるいは間接的に仮想関数を呼び出すことができます。 この場合、呼び出される関数は A で定義されているものか、A の基底クラスであり、A から派生したクラスでオーバーライドされた関数ではありません。 これにより、コンストラクター、またはデストラクターから、非構成オブジェクトにアクセスする可能性を回避します。 次の例は、このことを示しています。

#include <iostream>
using namespace std;
 
struct A {
  virtual void f() { cout << "void A::f()" << endl; }
  virtual void g() { cout << "void A::g()" << endl; }
  virtual void h() { cout << "void A::h()" << endl; }
};
 
struct B : A {
  virtual void f() { cout << "void B::f()" << endl; }
  B() {
    f();
    g();
    h();
  }
};
 
struct C : B {
  virtual void f() { cout << "void C::f()" << endl; }
  virtual void g() { cout << "void C::g()" << endl; }
  virtual void h() { cout << "void C::h()" << endl; }
};
 
int main() {
  C obj;
}

次に、上記の例の出力を示します。

void B::f()
void A::g()
void A::h()

例では obj いう名前で型 C のオブジェクトを作成しますが、B のコンストラクターは、CB から派生しているので、C でオーバーライドされた関数は、どれも呼び出しません。

コンストラクター、またはデストラクターで typeid または dynamic_cast 演算子を使用でき、同様に、コンストラクターのメンバー初期化指定子も使用できます。

関連参照

IBM Copyright 2003