まず、あなたの誤解は名前空間とは何staticの関係もありません。それはについてだけです。この回答の残りの部分でtestNumは、名前空間にあるという事実は無関係であるという理由だけで参照します。
また、おそらく関数と呼ばれる別のファイルがあり、関数test.cppを含みtest.h、定義していると仮定しますsetNum。
名前空間スコープの変数または関数(つまり、クラスメンバーではない、または関数のローカルではない)が宣言されstaticている場合、それはエンティティの名前がそのファイルの内部にあることを意味します。正式には「内部リンク」があります。つまり、名前で参照したり、他のファイルからリンクしたりすることはできません(ポインターを介して間接的に参照したり、別の関数に引数として渡すことで参照できます)。ファイルが定義するstatic int testNumと、各ファイルには、他のすべてのファイルとは異なる、その名前の独自の内部変数がありtestNumます(実際、1つのファイルが持つ可能性がstatic int testnumあり、別のファイルが持つ可能性があり、static double testnum別のファイルが持つ可能性がありstatic char* testNumます。これらはすべて、各ファイルに対して別個で内部的なものになります)。そのような定義をヘッダーに入れると、ヘッダーを含むすべてのファイルに独自のがありtestNumます。
したがってstatic、ヘッダーの変数には、を含むすべてのファイルで呼び出される異なる変数があります。つまり、1つのファイルに設定し、それを使用する別のファイルで関数を呼び出すと、同じ名前の別の変数が参照されます。testNumtest.htestNumtestNum
このため、ヘッダーで非定数static変数を宣言することはほとんどの場合間違っています。
これがないと、を含むすべてのファイルに変数staticの定義がありますが、これは許可されていません。すべてのエンティティは、プログラムで1回だけ定義する必要があります。これを解決する方法は、ヘッダーで変数を宣言することですが、定義はしません。これは、コンパイラーに変数を指示することによって行います。testNumtest.hextern
extern int testNum; // N.B. no "= 1" here
これは、コンパイラに「外部リンケージ」と呼ばれる変数があることを示しているtestNumため、コードが参照する場合、testNum常に同じ変数を意味します(すべてのファイルで異なるエンティティである内部リンクを持つ名前ではありません)。extern変数を宣言した後は、プログラムのどこかに正確に1つの定義が提供されていることを確認する責任があるため、正確に1つのファイル(つまり、複数のファイルに含まれるヘッダーではない)で定義します。
int testNum = 1;