いろきゅうの(元)はてなダイアリー

はてなダイアリーから移行中…

staticメンバが怪しい…?

相変わらず、DirectXのプログラミングをしているのです。コードの中には、staticメンバを含むクラスもあるのですが…なんだか、このstaticメンバの挙動がおかしい気がします。実行時に云々…という話ではなく「ビルド段階で」おかしいような…。
以下再現方法。長くなりますがごめんなさい。
(VS.NET 2003で試してます。VC6は確実にビルドエラーだと思います。2002は、よく判らず ^^;)

1、プロジェクトを作る。(仮に"t00"という名前とします。)
2、以下のようなコードを打つ。(ファイルも応じて追加してね。)

//-- t00.h -----
#pragma once
class A{
 
static const int n; // *1
public:
 
int Get();
};

//-- t00.cpp -----
#include "t00.h"

const int
A::n = 9;  // *2
int
A::Get(){
 
return n;
}


int
main()
{
  A a;
  a.Get();
};

//-- t00a.h -----
#pragma once
#include
"t00.h"
class C{
public:
 
int Get();
};

//-- t00a.cpp -----
int C::Get(){
  A a;
 
return a.Get();
}

 

3、で、ビルドする。コレは正常に通ってくれます。が!


4、*2 の “= 9” を切り取って *1 のお尻に持って行きます。つまり
static const int n = 9; // *1
const int A::n; // *2
というコードに変えます。ちなみに、コレも通ります。


5、今度は、*1 にある 数字の 9 を、0とかに変えてみると……「error LNK2005: "static int const A::n" は既に定義されています。」 ってなんでやねん。値変えただけなのに…。

6、なんだかよく判らないので、*2 の行をコメントアウトしてみるとコンパイルが通ってみたり。

7、更になんだかよく判らないので *2コメントアウトを戻してみると、やっぱりコンパイルが通ってみたり

8、*2コメントアウトして、*1の初期化もやめてみてもコンパイルが通ります。

9、この状態で *2コメントアウトを外すと「const 変数が初期化されません」とか…。


 


何ですかコレは… orz


ん〜、なんか、こう書いていて思ってみたんですけど、staticなメンバ変数をクラス定義内で初期化した場合、インスタンスを作っちゃいけないような気がしてきました…。(*2のことを指してます。用語の使い方間違ってたらすんません^^;)

ただ、そうすると4の時点でビルドエラーが発生しないのがまた謎。う〜ん…。マシン再起動したら、コンパイラの挙動が治るとかは無いだろうし…(ぶっちゃけ試してない ^^;)





…あぁ、判りました。


「仕様」ですか♪

…orz