2012-04-05 50 views
0

我正在處理我的引擎的核心問題,我在Microsoft Visual C++ express中遇到了嚴重的鏈接問題。命名空間和包含文件的C++鏈接錯誤

爲了簡化,引起問題的是這兩個頭文件,每個頭文件都有一個帶有不同標識符的名稱空間。這兩個文件實際上都包含對方。編譯沒有錯誤,但是在鏈接時,錯誤顯示「X已經在A.obj中定義」。一個例子如下規定:

端頭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

簡短的答案是:沒有包含對方的標題。 – 2012-04-05 00:27:17

+0

好吧,是的,我有一種感覺,它可能會導致一些問題,但是我怎麼能讓標題1的cpp訪問標題2,反之亦然。或者這是我設計中的嚴重缺陷? – 2012-04-05 00:30:10

+0

他們不能直接訪問彼此。所以也許你需要一些[前向聲明](http://en.wikipedia.org/wiki/Forward_declaration)。 – 2012-04-05 00:31:23

回答

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

完美的約書亞,我不能要求更好的答案。我只是試了一下,沒有更多的錯誤。萬分感謝! :) – 2012-04-05 00:48:13

1

的問題不在於你是包括多個命名空間相同的變量名,那就是你定義變量的頭,而不是僅僅聲明他們。這使編譯器爲每個包含標題的編譯單元創建一個這些變量的副本,並且這些變量在鏈接時發生衝突,這就是爲什麼會出現錯誤。

使用的extern剛剛宣佈他們的頭,而不是將它們定義:

端頭1

#ifndef HEADER1_H 
#define HEADER1_H 

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

首部2

#ifndef HEADER2_H 
#define HEADER2_H 

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

然後在相應的.cpp文件爲您的兩個標題,把你的namespace Core { int x, y, z; }namespace GUI{ int x, y, z; }

+0

這是否意味着我在頭文件和cpp中聲明瞭名稱空間? – 2012-04-05 00:43:36

+0

@JoeyPla你不必一次性聲明整個名稱空間 - 你可以在多個地方寫你的名字空間Foo {...},內容累積 – je4d 2012-04-05 00:45:13

+0

好的謝謝! – 2012-04-05 00:56:43