第 7 章: コンストラクタとデストラクタ

コンストラクタ

コンストラクタは, そのクラスをインスタンス化したときに, 自動的に呼び出される特別なメンバ関数:

class CSample{
private:
  int m_num;

public:
  CSample(); // コンストラクタの宣言
  int Get();
};

// コンストラクタの定義
CSample::CSample(){
  m_num = 100;
}

コンストラクタの名前はクラス名と同じ.

コンストラクタはあるクラスのメンバ変数を初期化するために利用される.

注意:

コンストラクタを通常の関数呼び出しで呼び出すことができない. あくまでも自動的に呼び出される.

ここで, 確認しておくが, 次の文はクラスをインスタンス化していない:

CSample *p;

これはポインタを宣言しているだけで, クラスの実体 ([インスタンス]) は作られない. よって, これだけではコンストラクタは呼び出されない.

デストラクタ

デストラクタは, クラスのインスタンスが解体されるときに, 解体の直前で自動的に呼び出される.

デストラクタの定義の仕方は次のようになる:

class CSample{
private:
  int m_num;

public:
  ~CSample(); // デストラクタの宣言
};

// デストラクタの定義
CSample::~CSample(){
  std::cout << m_num << std::endl;
}

省略した場合

コンストラクタとデストラクタは省略する場合は, 実はコンパイラが自動的にコンストラクタとデストラクタを生成している.

動作を確認するプログラム

sample.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// sample.h
class CSample{
 private:
  int m_num;

 public:
  CSample(); // コンストラクタの宣言
  ~CSample(); // デストラクタの宣言
  void Set(int num);
};

sample.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// sample.cpp
#include <iostream>
#include "sample.h"

// コンストラクタの定義
CSample::CSample(){
  std::cout << "コンストラクタが呼び出された" << std::endl;
}

// デストラクタの定義
CSample::~CSample(){
  std::cout << "デストラクタが呼び出された" << std::endl;
}

// m_num に値をセット
void CSample::Set(int num){
  m_num = num;
}

main.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// main.cpp
#include <iostream>
#include "sample.h"

/* 関数のプロトタイプ宣言 */
void func();

int main(){
  func();

  return 0;
}

void func(){
  CSample obj; // ここでコンストラクタ呼び出し
  obj.Set(123);

  std::cout << "Set メンバ関数を呼び出した" << std::endl;
} // ここでデストラクタ呼び出し

GNUmakefile

.SUFFIXES: .o .cpp
.cpp.o:
	$(CC) -c $(CFLAGS) $<

PROG = main
CC = g++
CFLAGS = -g -Wall
SRC = sample.cpp main.cpp
OBJ = sample.o main.o

hist: $(OBJ)
	$(CC) $(CFLAGS) -o $(PROG) $(OBJ)

.PHONY: clean
clean:
	$(RM) $(PROG) $(OBJ) *~ a.out

main.o: sample.h main.cpp
sample.o: sample.h sample.cpp

上記プログラムの実行結果は:

[wtopia constructor]$ ./main
コンストラクタが呼び出された
Set メンバ関数を呼び出した
デストラクタが呼び出された