標頭檔案命名空間問題

2021-10-07 15:29:39 字數 2275 閱讀 5271

在這裡,我毫不迴避地說了這句話: 

我再也不想在任何標頭檔案中看到「using namespace ***;」了

作為乙個開發者/團隊領導者,我經常會去招聘新的專案成員,有時候也幫助其他組的人來面試應聘者。作為應聘流程之一,我經常要求應聘者寫一些**,因此我檢查過相當多的**。在最近提交的c++**中,我注意到乙個趨勢,在任何標頭檔案中,我總是能看到以下**: 

using namespace std;
std::vectornames;

my_cool_reimplementation::vectorothernames;

現在,假定我們正在嘗試減少**輸入,並且在以上**中使用using宣告(或者更糟糕的,兩個命名空間都宣告了),按照如下**來實現: 

vectornames;

vectorothernames;

如果這段**的作者很幸運的話,編譯器會選擇vector的正確實現,或者至少在最初的階段會這麼做。但是過了一段時間,你會碰到一些很奇怪的編譯器錯誤。幸運的話,你能找到這些錯誤的原因——我曾經遇到過類似問題,我花費了好幾天才能找到這類問題的原因。該死,它們會浪費你很多的時間,僅僅因為你為了想少打5個字元的**。 

並且,如果你把using宣告用在了標頭檔案中,你會讓這類問題(編譯錯誤)更加惡化,因為命名衝突問題早晚都會在乙個呼叫關係非常非常遠的模組中神不知鬼不覺的出現,而你可能需要查三層呼叫才可以找到原因所在,乙個標頭檔案包含了另乙個直接使用using宣告的標頭檔案可以導致命名空間被立刻汙染掉,任何乙個使用命名空間的檔案如果使用了std命名空間的內容,都會導致這類問題。 

那麼,為什麼你能在很多教科書中看到它們使用using namespace std?我的理論是,它確實會幫助改善整本書的排版,並且能減少一些視覺的混亂。在一本紙質書中,你只有很有限的空間來寫文字,因此你必須最大限度的利用它,加之書中的**例子通常都很簡單。但另一方面,不同的命名空間限定符會帶來了很多視覺混亂,這會讓讀者很難從上下文判斷作者的意圖。當你想在這個時**一些有效率的**的時候,以上兩點都不完全對,現在的編譯器大多數能每行處理60-80個單詞(你可以試試,這可以的)。因此,不要亂引入命名空間。 

如果你非常明確的想在乙個標頭檔案中使用using宣告,應該怎麼做?我們有其他途徑可以減少不得不用using宣告的情況 —— 你可以用以下其中一種,或則多種方式的組合。 

首先,你只需使用typedef。我會建議你使用這種方法,即使我並不經常遵循我自己的建議,我也認為無論如何這都是乙個在實際應用中很好的方法。實際上,使用typedef有兩個好處 —— 它讓乙個型別名可讀性增加,如果你選擇了乙個很好的名字,它可以讓作者的意圖更加顯而易見。比較一下如下的宣告方式: 

std::mapclientlocations;

typedef std::mapclientnametozip;

clientnametozip clientlocations;

第二個宣告 —— 即使它被展開為兩行 —— 也比第乙個宣告更加直觀,同時,它也避免了命名空間模糊化。 

另外乙個選擇則是用兩種方法來限制using宣告的作用域 —— 僅僅是你想用的那個「using」符號,例如: 

using std::string;
但是,把這段宣告扔到頭檔案中,幾乎和使用「using namespace」一樣糟糕,因此,你應該使用作用域來限制它的可見性,來確保你的using宣告真的只在第一次做using宣告的地方有效。例如,你可以用如下方法限制類宣告作用域: 

namespace bar

;

}

class foo

;

或者,你可以直接把using的作用域限制到乙個函式中,例如: 

void temp()

不管哪種方法,你都可以把using的作用域限制到需要使用它的**中,而不是把它放到**的公共空間中。

你的工程越大,確保模組化,和最小化不可預料的負面影響就顯得越發重要。 

c 命名空間及標頭檔案

命名空間是1998c 標準新增特性 c 自98才標準化 命名空間 用來解決不同模組可能有識別符號衝突的問題。c 標註庫使用了乙個命名空間std,即c 標註庫中所有的識別符號都定義在命名空間std中。使用c 標註庫中的任何識別符號的方式有三種 1.直接指定識別符號號 如 std cout 標頭檔案he...

標頭檔案 命名空間書寫規範

菜鳥程式設計需要知道的規範。1,標頭檔案盡量包含在cpp檔案裡,而不是 件裡 2,不要在標頭檔案中使用using namespace 經常在標頭檔案中使用namespace。但這樣的結果就是,這個標頭檔案會被其他的檔案所包含,那麼這樣那個檔案也用了namespace所指定的命名空間,這並不是我們所期...

C 標頭檔案和std命名空間

c 是在c語言的基礎上開發的,早期的 c 還不完善,不支援命名空間,沒有自己的編譯器,而是將 c 翻譯成c 再通過c編譯器完成編譯。這個時候的 c 仍然在使用c語言的庫,stdio.h stdlib.h string.h 等標頭檔案依然有效 此外 c 也開發了一些新的庫,增加了自己的標頭檔案,例如 ...