これはC++に慣れていない人が陥りやすい誤りです。
staticなメンバ変数は、クラス定義の外に"定義"を書く必要があります。
これを書かないと、staticなメンバ変数は実体が確保されないため、麗さんが
書かれたようなリンクエラーになります。修正を下に載せます。
#include <iostream>
class piyo {
public:
// piyo(){ str = "Hello!!"; } <=== 削除
static void func();
private:
static char* str;
};
char * piyo::str = "Hello!!"; <=== staticメンバ変数の"定義"(同時に初期化も)
void
piyo::func()
{
std::cout << str << std::endl;
}
main(void)
{
piyo::func();
} 長くなりますが、考え方を書きます。(正確かどうか自信がないですが…)
まず、非staticなメンバ変数の場合は、各インスタンス毎に1つずつ領域が確保
されます。よって、クラス"定義"の中に int a; と"宣言"するだけで、実際に
インスタンスが作られる際に自動的にaの領域も(インスタンスの一部として)
確保されます。
ここまでは、意識しなくてもできてしまう部分です。
ところが、staticなメンバ変数の場合は、クラスに対して1つだけ確保される
ものです。しかも、確保されるタイミングは、インスタンスの生成とは無関係で
実行時の最初(global変数と同じ)です。
そのため、クラス定義の中に static int a; と"宣言"を書いただけでは、実体
が確保されません。宣言に加えて、クラス定義の外に"定義"を書いて、初めて
メモリ内に実体が確保されます。
つまり、メンバ関数の"定義"と同じです。メンバ関数も各インスタンス内に関数
の実体(=マシン語の列)があるわけじゃなくて、実行時の最初に1つだけ確保
されるはずですよね。
|