理系学生日記

おまえはいつまで学生気分なのか

メンバイニシャライザを使おう

以下のコードを実行すると,クラス B の構築時に暗黙のうちにクラス A のコンストラクタが呼び出され,メンバの a が構築される.結果として "constructor A" なる文字列が出力されることになる.

#include <iostream>
class A {
public:
  A() { std::cout << "contructor A" << std::endl; }
};

class B {
private:
  A a;
public:
  B() {}
};

int main() {
  B b;
  return 0;
}

クラス B のコンストラクタ中でクラス A のコンストラクタを明示的に呼び出すように変更してみると,

#include <iostream>

class A {
  int i;
public:
  A() { std::cout << "contructor A" << std::endl; }
  A(int i) { std::cout << "contructor A'" << std::endl; this->i = i; }
};

class B {
private:
  A a;
public:
  B() {
    a = A(10);
  }
};

int main() {
  B b;
  return 0;
}

出力は以下のとおり.

contructor A
contructor A'

A のコンストラクタが 2 度呼び出されることになってムダな感じだ.クラスの構築中に重い処理とかがあると悲しいことになるし,もし引数をとらないコンストラクタがクラス A に定義されてなかったら,コンパイルすらできなくなったりする.

何が原因かというと,メンバイニシャライザを使わないと,勝手にメンバのデフォルトコンストラクタが呼び出され,その後コンストラクタ中の処理が行われることになる.

メンバイニシャライザを使おう.

class B {
private:
  A a;
public:
  B() : a(10) {}
};