2010-11-17 70 views
3

爲純粹的組織目的使用子命名空間會被認爲是不好的做法嗎?例如:組織不良實踐的子命名空間?

namespace vehicles 
{ 
    namespace cars 
    { 
     // Stuff here 
    } 

    namespace boats 
    { 
     // More stuff here 
    } 
} 

我可以看到這將是對大項目的一個問題,因爲這會帶來不便鍵入vehicles::cars::function很多。但是,小項目呢?

+0

要看什麼東西,更多的東西 – 2010-11-17 18:15:05

+0

另外請注意,在小程序中觀察風格的唯一原因是適應大程序的預期。風格,良好的做法,設計模式等等在小程序中很少涉及,因爲它們中的大多數用於易於維護和容易擴展 – 2010-11-17 18:16:52

回答

7

爲什麼在一個小型項目中輸入vehicles::cars::function很不方便?

記住命名空間應該服務的目的。他們應該避免名稱衝突,而不是其他。

如果你發明了這樣一個令人費解的命名空間結構,我試圖將幾個using namespace ...放在每個文件的頂部,那麼它就會破壞命名空間的目的。

它也沒有告訴我很多我不知道已經。你打算在你的boats命名空間中放置什麼,我不知道這個名字本身就是一艘船?我是否需要在命名空間中的任何內容上澄清「這屬於船隻」?很可能不會,然後命名空間沒有意義。

一般情況下,不問什麼問題與使用任何語言功能,直到你發現了優點是什麼是。每個功能都需要證明自己。那麼你提出的命名空間會解決什麼問題?

如果它不能解決真正的實際問題,那麼這是一個壞主意,不管別的。

我一直認爲看看不同語言的標準庫是有益的。

.NET使用長名稱的深層嵌套命名空間。簡單動態數組的全名是System.Collections.Generic.List<T>

因此,沒有人使用命名空間。每個人只需將using System.Collections.Generic放置在需要使用List的每個文件的頂部。

正因爲如此,遇到困難的那一刻你還會碰到另一個List class。你會想要做同樣的事情,瞧,你有兩個類衝突。

C++使用非常平坦的namespcae結構,其中名稱空間的名稱也很短。

C++中的等效類只是std::vector。因此,人們通常會輸入名稱空間前綴,因此,當我將另一個矢量類添加到我的項目中時,它會起作用。沒有名稱衝突,因爲當我想引用標準庫向量時,我使用前綴std::

+0

我會與「而不是其他」部分爭論。我認爲命名空間中最有價值的東西是ADL,並且可以將獨立函數包含到類的接口中 – 2010-11-17 18:18:06

+0

@Armen:你也可以使用沒有命名空間的類。最終,命名空間是*細分*你的代碼。 ADL是一種避免這種情況的方式,將代碼捆綁在一起。 – jalf 2010-11-17 18:19:04

+0

@Armen:但我同意ADL是使C++中的命名空間*工作*的重要組成部分。如果沒有這些,我們最終可能最終會在C++中的任何地方放置'using namespace ...',否定命名空間的優點。 – jalf 2010-11-17 18:23:06

3

恕我直言,這不是不好的做法!還要考慮使用別名來避免必須每次輸入完全限定名稱,而不是在需要時注入整個名稱空間......

2

命名空間的其中一個原因是爲了組織目的,你如何使它們細化到個人偏好 - 我個人喜歡它們是相當通用的,例如我有TransferObjects。交通工具,但不是那麼細緻。除非你有很多很多類型,否則我沒有看到詳細說明。但這取決於你。

如果這是一個小項目,那麼代碼庫應該相對較小並且易於導航,從而消除了對這種方法的需求?

4

那麼,爲了什麼是值得的,我在幾年前嘗試在一箇中等規模的項目上使用深層嵌套的命名空間,而且這絕對是地獄 - 我花了我的整個時間來編寫typedefs :)在Java中,包工作得非常好,因爲你可以在每個.java文件的頂部導入東西,而不會遇到大問題。在C++中,這是一個令人頭疼的問題,因爲在頭文件中使用僞指令/聲明是一種不好的做法 - 因此,您最終要麼(a)使用頭文件(bleurgh)或(b)完全限定所有內容大量的typedefs(也bleurgh)。不冷靜 - 我的建議是,以避免瘟疫一樣,除非你喜歡寫的東西,如:

centipede::autoseg::hierarchygeneration::ragbuilders::RAGBuilder<...> 

這不是一個類型,它是一個句子......

+0

爲什麼你會使用typedefs呢?我認爲'使用'指令將是正確的工具。當然你不會把它們放在頁眉的頂部,但是你可以在本地使用它們,在函數內部,它們不會污染任何東西。如果你在一個函數中使用了很多東西,那麼在函數的頂部放一個'using abcd :: efgh :: MyClass;'。另一種方法是使用本地'namespace po = boost :: program_options;'來縮寫命名空間。 – Ela782 2015-06-30 14:05:42

+0

@ Ela782:你可以把函數放入函數中(儘管你必須在每個函數中重複它們),但是如果你這樣做,你仍然不得不完全限定成員變量的類型。你可以在沒有typedefs的情況下將你的類包裝在一個虛擬的命名空間中,用using指令將它們導入到這個命名空間中,然後將你的類導回到封閉的命名空間中,但是這會變得有些詭異。命名空間的縮寫可以起作用,但可以說阻礙了可讀性的一點,並有助於解決您最初不存在的問題(over-nested namespaces)。 – 2015-07-01 00:22:54

+0

好的,我也同意你的最後一句話:-)你是什麼意思與_「你仍然最終不得不完全限定成員變量的類型」_? – Ela782 2015-07-01 20:54:15