2012-06-17 18 views
14

私は4つのファイル(2つのヘッダーと2つのコードファイル)を持っています。 FileA.cpp、FileA.h、FileB.cpp、FileB.hC++変数の複数の定義

FileA.cpp:

#include "FileA.h" 

int main() 
{ 
    hello(); 
    return 0; 
} 

void hello() 
{ 
    //code here 
} 

FileA.h:

#ifndef FILEA_H_ 
#define FILEA_H_ 
#include "FileB.h" 
void hello(); 

#endif /* FILEA_H_ */ 

FileB.cpp:

#include "FileB.h" 

void world() 
{ 
    //more code; 
} 

FileB.h:

#ifndef FILEB_H_ 
#define FILEB_H_ 

int wat; 
void world(); 


#endif /* FILEB_H_ */ 

コンパイルしようとすると(「eclipse」で)「ワット」の多重定義が得られる そして、なぜそれがうまくいくかはわかりません。

+4

リンクの世界へようこそ。 –

答えて

22

私はすべての詳細を含めるつもりはありませんが、あなたはあなたのコンパイルUINTに二回グローバル変数、watを定義します。次を使用し、固定するために

FileB.h

extern int wat; 

FileB.cpp

int wat = 0; 

この(extern)変数watコンパイルを伝えます存在するどこか、そして問題はコンパイラが作成することです (私はファイルで助けを次々に見て推測)私は今の答えを見つけた

+0

'const'変数の最適化に影響しますか?コンパイラ最適化はコンパイル段階かリンク段階で実行されますか? – ar2015

0

wat変数宣言は、cppファイルに属するべき定義です。これは、関数本体をヘッダに入れるかのようです。

ワット宣言の前にexternを置いて、externのない現在の宣言をcppファイルの1つにコピーする必要があります。

3

watがファイルスコープで宣言され、2つのソースファイルでgetが2回表示されるため、複数の定義が得られます。

代わりに、変数宣言externを作成し、正確にソースファイルに定義します。

extern int wat; // In FileB.h 

int wat; // In FileB.cpp 
1

(この場合には、それはFileB.cppにあります)、それはそれ自身でそれを見つける必要があることワットの定義が であるFileB.oを作成し、FileA.c.hでFileB.oをコンパイルしようとしますが、FileA.hにはFileB.hのインクルードが含まれています。

+0

私は1つのblabla.hファイルとインクルードガード(#ifndef xxx_H ...)と1つのグローバル変数のみを持っています。コンパイル時に、私は 'myglobal_variable'エラーの多重定義を得ました。 –

6

変数をヘッダに宣言しないでください。 #includeは、ファイルの内容をそのままコピーして別のファイルに貼り付けます(つまり、#include "FileB.h"は、ファイルに内容をコピーします。つまり、#include "FileB.h"のすべてのファイルでint watが定義されます)。

FileA.cppからwatにアクセスし、FileB.cppで宣言している場合は、FileA.cppにexternというマークを付けることができます。