2012-02-02 31 views
2

我們通常使用名稱空間來避免C++中的名稱衝突。但是如果有兩個不同的庫有一個類,它具有相同的名稱空間名稱和類名?有沒有解決辦法?即使在使用命名空間之後還有名稱衝突怎麼辦?

(PS:我敢肯定,它的一個罕見的情況下,我從來沒有遇到它,剛好過我的腦海)

+0

0_o,起訴這兩個圖書館的創造者? xD – 2012-02-02 15:59:36

回答

0

它可能發生,但它不太可能會對你造成很大的傷害。不僅命名空間名稱必須完全相同,您必須實際使用這兩個庫。很有可能,如果他們已經以某種合理的方式命名了他們的名字空間,他們的名字將表明他們的目的 - 即使有兩個庫使用GenericXMLParser作爲他們的名字空間,並且可能有一些共同的類名,你是否真的期望在一個項目中使用它們?

這確實使某些命名空間名稱是一個糟糕的主意,例如boostOgre。任何人使用這些(除原來的用戶)應該期望他們的庫在許多情況下不可用。一個不太常見的名字,如Pie,在絕大多數情況下,對於絕大多數人來說可能會很好。如果兩個使用Pie的庫被廣泛使用,則可能需要更改;在這種情況下,可以使用名稱空間重命名技巧來保持與舊代碼的向後兼容性。

1

的想法是使用相關的公司/集團本身的東西。
這樣避免了碰撞。
專業圖書館很難選擇像MyNamespace這樣微不足道的東西。

它會像Company::Project::Module

,你必須org.apache etc

+0

Java方案的優點是存在名稱所有權的中央註冊表。即使每個人都是專業人士,如果在不同國家/地區有兩個或多或少同名的組織,C++問題也會出現。在Java中,它們是'com.apple'和'uk.co.蘋果「,但在C++中,你最好只希望他們在開始發佈使用命名空間」apple「的C++庫之前就知道這個問題。 – 2012-02-02 16:08:16

+0

就我個人而言,我不會訂閱使用已久的公司名稱作爲命名空間名稱:公司消失的機會比其代碼更好:它們經常消失,因爲它們被另一家公司掌握代碼。辯護?有創意,不要打電話 – 2012-02-02 17:31:46

+0

@DietmarKuhl:你有一點,但是當你爲一家公司編寫代碼時,它是公司的專利。所以你不能隨意使用慣例。同一產品線應該有一致性。 – Cratylus 2012-02-02 17:46:40

0

可以重命名的命名空間中的一個與

namespace <new> = <old>; 

但只會讓你至今這甚至在Java清晰。這裏有一個例子:

namespace aaa { 
    int foo() { return 42; } 
} 

namespace zzz { 
    int foo() { return -42; } 
} 

namespace bbb = aaa; 

int main() { 
    aaa::foo();   //Original namespace is still there 
    bbb::foo(); //but it is also available with a new name 
    zzz::foo(); //No clash, that's what namespaces are for 
    return 0; 
} 

但由於更名真的只是一個別名,該aaa命名空間停留。此代碼將讓你重複的符號錯誤(不管它是如何深.h文件葬):

namespace aaa { 
    int foo() { return 42; } 
} 

namespace aaa { 
    int foo() { return -42; } 
} 

你可以避開它以某種方式通過包裝爭食命名空間在自己的命名空間聲明,如下所示:

#include <stdio.h> 

namespace aaa { 
    int foo() { return 42; } 
} 

namespace zzz { 
#include "clash.h" 
} 

namespace aaa2 = zzz::aaa; 

int main() { 
    printf("%d\n", aaa::foo()); //Original works 
    printf("%d\n", aaa2::foo()); //Non-clashing through alias 
    printf("%d\n", zzz::aaa::foo()); //Non-clashing real name 
    return 0; 
} 

但是該解決方案也將在瑣碎的代碼只工作,因爲所有在clash.h包含文件將在zzz命名空間中結束。

+我認爲重命名std雖然只是通過常識是被禁止的。

+0

這沒有幫助,您仍然無法在同一個可執行文件中鏈接這兩個類。 – 2012-02-02 16:05:52

+0

我不知道這意味着什麼 – 2012-02-02 19:17:19

+0

@SteveJessop是對的。只要你不需要鏈接,這個技巧就可以工作;)我編輯了我的答案。 – ixe013 2012-02-03 16:02:22