2017-01-07 2 views
0

Example.h:2の.CPPファイルでこのヘッダーファイル(ヘッダーガードあり)を含むと、名前付けの衝突が発生するのはなぜですか?

#ifndef EXAMPLE_H 
#define EXAMPLE_H 

#include "stdafx.h" 
#include <Windows.h> 


namespace Test 
{ 
    DWORD foo; 
} 

#endif 

Example.cpp:

#include "stdafx.h" 
#include "Example.h" 

Example2.cpp:

#include "stdafx.h" 
#include "Example.h" 

MAIN.CPP:

#include "stdafx.h" 

int main() 
{ 
    return 0; 
} 

これがもたらしますリンカーエラー:

error LNK1169: one or more multiply defined symbols found 
error LNK2005: "unsigned long Test::foo" ([email protected]@@3KA) already defined in Example.obj 

"Example.h"が "Example2.cpp"に含まれていない場合、このコードはコンパイルされます。私の理解では、Example.hはこの例では一度しか含まれません。それが本当であれば、なぜfooの名前の衝突がありますか?

+1

おめでとうございます。なぜ、ヘッダーファイルで宣言されたグローバル変数が悪いのかを知りました。私はこれをもっと多くの人々に渡すことができたらいいと思う。 –

答えて

4

ヘッダーガードは、複数のインクルードを同じで保護します。translation unit(ソースファイル)。異なる翻訳単位での複数の包含から保護するものではありません。

したがって、両方のソースファイルに変数Test::fooを定義します。

1つの解決策は、ヘッダーファイルの変数宣言をexternとマークすることです。単一のソースファイルでは、定義としてヘッダファイルの宣言を基本的に複製します(externキーワードなし)。

これは変数でのみ発生し、クラスや関数などでは発生しません。

+1

IMHO、より良い*ソリューションは、グローバル変数の必要性を排除することです。 :-) –

+0

@ThomasMatthews:いつも可能でもスマートでもない。オブジェクトファクトリのように、多くのものは本質的にグローバルである。 –

関連する問題