C++コンストラクタとデストラクタ

コンストラクタとデストラクタについて

コンストラクタ(constructor)とは

コンストラクタとは、オブジェクト宣言時に初期値を設定する特殊な初期化関数です。

  • クラスの宣言の中に同名の関数があれば、その関数が自動実行されます。
  • コンストラクタは値設定などの初期化処理をするための関数であり、返り値を持ちません。そのため、関数の返り値を指定しません。(戻り値を指定すると、コンストラクタではなく関数として扱われます。)
  • コンストラクタは多重定義(オーバーロード)も可能です。

デストラクタ(destructor)とは

デストラクタとは、オブジェクトが消滅する時に後始末をする後処理関数です。

  • クラス名の先頭に「~」チルダを付けることで定義します。
  • 戻り値や引数を指定することはできません。
  • 呼び出される時点は、オブジェクトが消滅する時(delete実行や関数を抜ける時)となります。

コンストラクタとデストラクタの定義例

クラスポインタの場合、new時点でコンストラクタが呼び出され、delete時点でデストラクタが呼び出されます。


#include <iostream>

class cls{
public:
    int buff;

    // コンストラクタ
    cls(int temp){
        printf("constructor is called.\n");
        buff = temp;
    }
    // デストラクタ
    ~cls(){
        printf("destructor is called.\n");
    }
};

int main()
{
    cls *obj;

    obj = new cls(32);
    printf("%d\n", obj->buff);
    delete obj;

    return(0);
}

コンストラクタの初期化リスト

初期化リストとは

オブジェクト生成時のメンバ変数への代入は、初期化リストを利用することができます。

初期化リストを用いたコンストラクタは以下の形式となります。


クラス名(引数 ... ):初期化リスト { 関数本体 }

初期化リストを用いる利点は以下の通りです。

  • 引数からの代入に比べて、処理が高速です。
  • 代入の処理漏れを防ぐことも出来る。

#include <iostream>

class box{
private:
    int x;
    int y;
public:
    // 初期化リスト
    box(int a, int b): x(a), y(b){}

    // メソッド:面積を求める
    int surface_area(){ return(x * y); }
};

int main()
{
    box obj(5,7);
    printf("%d\n", obj.surface_area());
    return(0);
}

変換コンストラクタとexplicitについて

変換コンストラクタ(converting constructor)とは

変換コンストラクタとは、引数を一個だけを持つコンストラクタのことです。

引数を一個だけを持つコンストラクタについては、「暗黙的呼び出し」と「明示的呼び出し」の2つの呼び出し方があります。


CSample num1 = 10; // 暗黙的呼び出し
CSample num2(20);  // 明示的呼び出し

explicitとは

explicitキーワードは引数を一個だけを持つコンストラクタの暗黙の型変換を禁止します。

explicit宣言したコンストラクタは、明示的呼び出しでしか呼び出せなくなり、暗黙呼び出しを記述するとコンパイル時エラーになります。


#include <iostream>

class CSample{
private:
    int num;
public:
    explicit CSample(int num){ this->num = num; }
    int getCSample(void){ return num; }
};

int main()
{
    //CSample num = 10; // explicitによって暗黙的呼び出しはエラーとなる。
    CSample num(20);    // 明示的呼び出しは可能。
    printf("%d\n", num.getCSample());

    return(0);
}

関連ページ