2012-04-05 5 views
0

私のエンジンのコアに取り組んでいます。私はMicrosoft Visual C++ Expressに深刻なリンク問題があります。C++リンクの名前空間とインクルードファイルでのエラー

簡単にするために、問題を引き起こすのはこれらの2つのヘッダーファイルで、各ヘッダーファイルには異なる識別子の名前空間があります。これらのファイルは、実際には互いに組み入れられています。コンパイル時にエラーは発生しませんが、リンク時に "Xは既にA.objで定義されています"というエラーが表示されます。例を以下に提供される:

HEADER 1

#ifndef HEADER1_H 
#define HEADER1_H 

#include "header2.h" 
namespace Core{ 
    int x, y, z; 
} 
#endif 

ヘッダ2

#ifndef HEADER2_H 
#define HEADER2_H 

#include "header1.h" 
namespace GUI{ 
    int x, y, z; 
} 
#endif 

私はというエラーを取得しているが起こってしまうことのx、yおよびz変数はすでに作成された最初の.objファイルで定義されていました。私は変数が異なる名前空間から来ているので、衝突することはできないと仮定しました。私はヘッダーガードも持っているので、ヘッダーファイルは複数回含まれていないようです。

とにかく、どんな種類のヘルプやアドバイスをいただければ幸いです。私は約3日間このことに固執しています:P。また、十分な情報を提供していない場合は、私の現在のコードが非常に長いことを知らせてください。

乾杯、 ジョーイ

+3

短い答えは、お互いを含むヘッダーがないことです。 –

+0

申し訳ありませんが、私はそれがいくつかの問題につながるかもしれないという気持ちを持っていましたが、ヘッダー1のcppにヘッダー2へのアクセス権があり、逆も同様です。それとも私のデザインに深刻な欠陥がありますか? –

+0

彼らはお互いに「直接」アクセスすることはできません。だから、あなたはどこかで[前方宣言](http://en.wikipedia.org/wiki/Forward_declaration)が必要になるでしょう。 –

答えて

8

実際には、ヘッダーファイルに変数が定義されているという問題があります。ヘッダーファイルが含まれているわけではなく、ヘッダーを含む各.cppファイルに6つの変数がすべて定義されています。

各.cppファイルは.oファイルになり、各.oは変数が定義された状態になり、リンカエラーが発生します。あなたがしたいことは、実際に変数が他の場所で定義されていることをコンパイラに伝えるヘッダのexternキーワードを使うことです。(!一つだけのcppファイル内):例えば

namespace Core{ 
    extern int x, y, z; 
} 

、その後

namespace GUI{ 
    extern int x, y, z; 
} 

は、CPPファイルにユーザーが定義する必要にextern

namespace Core { 
    int x, y, z; 
} 
namespace GUI{ 
    int x, y, z; 
} 
せずに変数

これはリンカーのエラーを修正します。

+0

完璧なジョシュア、私はより良い答えを求めることができなかった。私はちょうどそれを試みたが、それ以上のエラーはなかった。ありがとう、トン! :) –

1

問題ではないあなたが複数の名前空間で同じ変数名を含めているということですが、それはあなたがそれらをヘッダに変数を定義するだけではなく、宣言だということです。これにより、ヘッダーを含むコンパイル単位ごとにこれらの変数のコピーが1つ作成され、リンク時にこれらの競合が発生するため、エラーが発生します。

だけではなく、それらを定義するよりも、ヘッダーでそれらを宣言する使用のextern:それぞれの中

HEADER 1

#ifndef HEADER1_H 
#define HEADER1_H 

#include "header2.h" 
namespace Core{ 
    extern int x, y, z; 
} 
#endif 

HEADER 2

#ifndef HEADER2_H 
#define HEADER2_H 

#include "header1.h" 
namespace GUI{ 
    extern int x, y, z; 
} 
#endif 

そして、あなたの2つのヘッダーのファイルを.cpp個入れてください。namespace Core { int x, y, z; }namespace GUI{ int x, y, z; }

+0

これは、ヘッダとcppの両方でネームスペースを宣言していることを意味しますか? –

+0

@JoeyPla名前空間全体を一度に宣言する必要はありません。名前空間Foo {...}を書く場所は複数あり、内容は蓄積されます – je4d

+0

ありがとう! –