2010-01-15 29 views
3

有點學術問題,但我在編寫一些單元測試時遇到了這個問題。C++/VS2005:在兩個不同的.cpp文件中定義相同的類名

我的單元測試框架(UnitTest ++)允許你創建結構來充當燈具。通常這些是針對文件中的測試定製的,所以我把它們放在我的單元測試文件的頂部。

//Tests1.cpp 

struct MyFixture { MyFixture() { ... do some setup things ...} }; 

TEST_FIXTURE(MyFixture, SomeTest) 
{ 
    ... 
} 

//Tests2.cpp 

struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}}; 

TEST_FIXTURE(MyFixture, SomeOtherTest) 
{ 
    ... 
} 

然而,我發現最近(與VS2005至少),當您使用相同的名稱命名夾具結構(所以現在具有相同的名稱存在於結構的兩個版本),那麼版本的一個被悄悄拋出。這非常令人驚訝,因爲我的編譯器設置爲/ W4(最高警告級別),並且沒有警告出現。我想這是一個名稱衝突,爲什麼命名空間是被髮明的,但是我真的需要將我的每個單元測試裝置都包裝在一個單獨的命名空間中嗎?我只是想確保我不會錯過更基本的東西。

有沒有更好的方法來解決這個問題 - 這是否應該發生?我不應該看到重複的符號錯誤或什麼?

回答

8

嘗試在匿名命名空間中粘貼類,您可能會發現它比爲每個文件創建並命名新命名空間更不令人討厭。

不要訪問VS2005和.cpp的單元,但是這可能工作..

//Tests1.cpp 
namespace 
{ 
struct MyFixture { MyFixture() { ... do some setup things ...} }; 
} 

TEST_FIXTURE(MyFixture, SomeTest) 
{ 
    ... 
} 


//Tests2.cpp 
namespace 
{ 
struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}}; 
} 

TEST_FIXTURE(MyFixture, SomeOtherTest) 
{ 
... 
} 
+1

+1,這是匿名命名空間旨在解決的確切問題 – 2010-01-15 22:18:59

+0

因此,預計兩個燈具中的一個會默默覆蓋另一個,而不是來自鏈接器的單詞? – 2010-01-15 22:24:14

+0

忘記吧 - 我明白了。我錯誤地/愚蠢地認爲名稱修改將應用於結構類型,因此鏈接器可以區分它們。 – 2010-01-15 22:43:11

0

這基本上是的,這導致有冗餘的事實,類需要在頭文件中定義,因此每個對象文件中類的定義。因此,一個可以處理C++連接的鏈接器必須將冗餘類聲明合併在一起,並假設該類只聲明瞭一次。

連接器沒有任何方法可以區分包含在多個對象中的單個類和多個對象中具有相同名稱的多個類。

你必須使用命名空間(或更好的語言)來解決這個問題。

+0

@Kornel:靜態的一個用途是使對鏈接器不可見的對象生成。鏈接器當然不能區分它們彼此看不到的對象。或者你還有其他觀點? – 2010-01-15 22:16:46

+0

是的,沒有注意到OP引用的類型不是變量 – 2010-01-15 22:19:25

+0

是的,請閱讀它。然後當你意識到它不適用時,請閱讀匿名命名空間。 – 2010-01-15 22:19:47

2

編譯器一次只能在一個編譯單元上工作;這將是源文件和它包含的任何內容。由於您的課程位於不同的檔案中,因此不存在衝突。

鏈接器將所有內容放在一起,但它不知道類定義,因此它也不會看到衝突。

早在C的時代,鏈接器很容易識別出你有兩個具有相同名稱的不同函數並生成一條錯誤消息。使用C++中的內聯函數和模板時,它不能再這麼做了 - 不同的編譯單元通常會包含相同函數的重複項,所以鏈接器只是假設它們是相同的。

相關問題