初期化リスト覚え書き

これは何?

どーにもこーにもお仕事に使っているC++になじめないので、苦手な部分、知らなかった部分を取りまとめてブログに書くシリーズです。
C++脱初心者を目指す人レベルと思ってます。
ちなみに環境は、主にVisual C++ 2005 Express EditionとVisual C++ 2005です。


と、言うわけで何回続くか判らないけど、初期化リストについて。

サブクラスのコンストラクタの順序

  1. スーパークラスがあれば、それのデフォルトコンストラクタを宣言の左順に実行
  2. スーパークラス内では、1〜4の処理を再帰的に実行
  3. クラスメンバに実体のクラスがあれば、それのデフォルトコンストラクタを実行
  4. 自身のコンストラクタの実行

通常のサブクラスのコンストラクタの弱点


そこで初期化リストですよ。

初期化リストとは?

コンストラクタにおいて、以下の事を行う処理

  • スーパークラスのコンストラクタの呼び出し順序を定義
  • 引数付きのスーパークラスのコンストラクタを呼び出す
  • メンバ変数の初期化
    • constや参照型のメンバ変数は、初期化リストでしか初期化できない。
      初期化しないとエラーが出る。
 error C2758: 'TestClass::i' : オブジェクト コンストラクタの初期化リストで初期化されませんでした。

書き方は?

コンストラクタ(引数) : サブクラス名(引数),メンバ名(引数)…
  • サブクラスと、メンバの書き順は任意。但し左から順に実行される。

具体的には?

class TestClass
{
private:
	const int i;

public:
	// デフォルトコンストラクタ
	TestClass() : i(0) // ←constのメンバ変数iを初期化
	{
		std::cout << "TestClass()" << std::endl;
	}

	// コンストラクタ
	TestClass(int i) : i(i) // ←constのメンバ変数iを初期化
	{
		std::cout << "TestClass(" << i << ")" << std::endl;
	}

	// メンバ変数iを表示
	void getI()
	{
		std::cout << "I = " << i << std::endl;
	}
};

class TestSubClass : public TestClass
{
private:
	const int j;

public:
	// コンストラクタ
	TestSubClass(int i, int j) : TestClass(i), j(j) // 引数付きサブクラスと、constメンバ変数jを初期化
	{
		std::cout << "TestSubClass(" << i << "," << j << ")" << std::endl;
	}

	// メンバ変数iを表示
	void getJ()
	{
		std::cout << "J = " << j << std::endl;
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	TestSubClass t = TestSubClass(1, 2);
	t.getI();
	t.getJ();

	char c[256]; std::cin >> c;
	return 0;
}

実行結果

TestClass(1)
TestSubClass(1,2)
I = 1
J = 2


そんな感じで初期化リスト便利。
特にコンストラクタで指定してそれ以降getしかしないメンバとかは積極的にconstにして初期化リストで初期化すべき。


そんなですー。