2011-10-06 137 views
0

在兩個不同文件(A.cpp,Ah,B.cpp,Bh)中,我有兩個相同類的版本,所有文件中類的名稱相同但內部實現不同。在不同文件中具有相同名稱的不同類版本

我的想法是通過更改#include中的.h文件的名稱從一個版本切換到另一個版本,所以我不應該更改代碼中的其他任何東西(兩個版本的方法都有相同的簽名和相同的屬性)

Ah和Bh從不包括在同一時間。

問題是無論什麼包括我總是使用的文件執行一個版本。我知道,當我包含B.h時,至少它是編譯的(通過在編譯時顯示一些代碼錯誤)

可以這樣做嗎?或者這是違反C++的一些規則?我認爲這不應該違反One Definition Rule,因爲我不同時使用A.h和B.h。

+0

問題是你如何鏈接目標文件?只是調整包括不起作用。 – pmr

+2

如果你包含B.h並且鏈接到B.o,你應該沒問題。你如何鏈接?但是如果這個班級的api是一致的,那麼A.h和B.h應該是相同的;他們爲什麼不同? –

+0

你包含的頭文件不會像你鏈接的實際代碼那麼重要。 – Joe

回答

2

解決方案是不要將舊文件鏈接到最終的可執行文件中。這樣只有新的實施將可用。

0

如果頭文件是相同的,只需要一個頭文件和兩個不同的實現文件就更容易了。這會將你的問題減少到只連接正確的目標文件。這也可以減少你的標題出現分歧時出現細微錯誤的機會。

當然,更好的解決方案是,不依賴於構建系統,而是使用語言工具在編譯時更改代碼,如模板。

+1

爲什麼模板會更好?版本管理是構建系統最好管理的典型案例。 –

+0

@詹姆斯我沒有印象,他有兩個不同的版本,但實際上只是兩個不同的接口實現。 – pmr

2

我經常做的是將版本打包到命名空間中,然後使用它。 沿線的一些東西:

namespace Xyz_A { // In A.h 
// Define version A 
} 

namespace Xyz = Xyz_A; 

;在B.h中,改爲使用_B

這樣,你會在你的程序寫Xyz::...,但外部 符號將有Xyz_AXyz_B錯位放進去。但在我的 選項中,這實際上更能防止錯誤。我會在我的makefiles中安排 的東西,這樣A.hB.h 之間的任何開關也會導致可執行文件鏈接到相應的庫,而不是針對其他文件。

+0

事實上,把兩個版本在不同的命名空間可以讓你編譯類的兩個版本到同一個可執行文件。除了簡化構建過程之外,它還允許您在各個版本之間編寫運行時切換(這對於根據配置文件或命令行中的設置選擇類版本可能很有用)。 –

+0

@AndréCaron在運行時不能在名稱空間之間切換。命名空間純粹是編譯和鏈接時間解析。 (我用的是不同的命名空間來檢測錯誤:編譯對一個版本,而像,動態或其他方式,對另一個。) –

+0

當然你也可以不是。然而,你可以寫一個簡單的開關,如'回報(use_version_A:新Xyz_A ::富():新Xyz_B ::富());'。如果您使用構建過程將其切換出來,則無法完成此操作。 –

0

您將需要加載正確的庫以匹配頭文件。

我建議尋找代理設計模式,以便您可以包括類A和B.然後,您可以使用代理來選擇在運行時使用哪個類函數。

http://en.wikipedia.org/wiki/Proxy_pattern

相關問題