自習室

こもります

staticなメンバ変数を正しく初期化する

クラスを定義して、.hと.cpp のファイルに分割する際にこれまでも何度か同じような引っかかり方をしてきた気がするのでメモ。

/*test.h*/
class test{
	static int my_intarray[10];  //ここがまずい
public:
	static void func();
};

/*test.cpp*/
#include "test.h"

void test::func(){
	test::my_intarray[0] = 1;
}

int main(){
	test::func();
	return 0;
}
/*以下略*/

のように、.h ファイルの中で具体的な領域の確保はできない。というか、「確保」という言い方自体がおかしい。なぜなら、上記の.h ファイルの中身はクラスの「定義」なのであって、インスタンスはmain中なりどっか別の場所で作られ、その際に初めてメンバ変数も具体的に領域を必要とするから。(だと思う)

このままコンパイルしようとすると visual studio 2008 では「リンク時に」次のように叱られる。

1>test.obj : error LNK2001: 外部シンボル ""private: static int * test::my_intarray" (?my_intarray@test@@0PAHA)" は未解決です。
1>C:\*****************\Projects\lnkerror\Debug\lnkerror.exe : fatal error LNK1120: 外部参照 1 が未解決です。

これを回避する方法を以下に。

/*test.h*/
class test{
	static int my_intarray[];  //ここでは定義だけ
public:
	static void func();
};

/*test.cpp*/
#include "test.h"

//このように、グローバルな場所で静的メンバ変数の実体を生成。
int test::my_intarray[10];

void test::func(){
	test::my_intarray[0] = 1;
}

int main(){
	test::func();
	return 0;
}

こんな具合に、cppの方でちゃんと静的メンバ変数の実体を作ってあげればOK