什麼是命名空間

2021-10-13 18:04:56 字數 2776 閱讀 8610

問題:學習過c,然後再學c++的人可能會這麼問,我#include之後,不就是把頭檔案拉進來了嗎,而cin cout等函式不就是iostream.h裡面的函式嗎,我使用cin cout時,編譯器為什麼會說 「error 未定義標示符」呢?

解決方法:這樣寫

#include

using

namespace std;

void

main()

但可能不知道為什麼加這句

我剛學c++時也不明白為什麼,看課本解釋說什麼命名空間的,看不明白,只是知道這樣寫才能通過編譯,也沒有深究,每次都默默加上去的說。

現在,任然是個菜鳥的說,看了一些資料之後,寫了這篇筆記「關於using namespace std;以及為什麼有的標頭檔案需要加上.h而有的標頭檔案不需要」,可能不夠嚴謹,歡迎指出錯誤。

這是個歷史問題。

這得從庫的概念說起,你#include進去的就是別人幫你寫好的庫,你可以直接呼叫標頭檔案裡面封裝好的函式或類,比如你用的cin cout等就是c++標準庫裡面的函式,這樣你就不用自己寫乙個函式cin 來實現輸入功能,也不用寫函式cout來實現輸出功能,直接呼叫就可以了。除了c++標準庫,一些公司封裝了一些函式,實現某些強大的功能,然後拿來賣,比如微軟的mfc ,trolltech公司的qt等,所以c++變得更加強大,不僅可以直接呼叫標準庫,還能呼叫別的公司封裝好的庫。

早期的c++庫內容有限,可隨著時間的推移,庫的功能越來越強大,每個廠商之間可能將庫裡面的函式或類取了相同的名字,比如說a公司的庫就可能定義了乙個叫做sum的函式,而b公司也定義乙個叫做sum的函式,於是就出現問題了,程式設計師開發時,如果同時使用了a的庫,又使用了b公司的庫,那麼就可能出現混亂,你呼叫的sum到底是哪家公司的。最初,人們就想了個辦法,廠商將名字取得更長更複雜來避免重複,可這樣做卻給編寫和閱讀帶來了困難。後來,人們創造了命名空間這個概念(2023年),它能有效地指出某個標示符到底屬於哪個庫。

通過使用 namespace ***;來說明你所用的這個函式或類來自於哪個庫或者是自己寫的函式。例如,c++標準程式庫就把標準庫庫裡面的函式或類的名稱放在乙個「叫做std的命名空間」,比如cin cout這兩個函式的名字就放放在命名空間std裡面,你可以通過std::cin std::cout來說明你這裡使用的cin cout是來自標準庫裡面的函式,而不是自己寫了個名字叫做cin的函式,也不是別的廠商的庫裡面的函式cin,但這樣也比較麻煩,每次呼叫的話就得把cin寫成std::cin,如果你想要經常可以在程式的開頭使用 using std::cin;來說明以下**所使用的cin是來自std這個命名空間,也就是標準庫裡面的函式。若程式需要大量地使用標準庫裡面的函式,就可以把using namespace std;放在程式的開頭,來說明以下**將使用標準庫的函式或類,程式設計師不能取和標準庫裡面衝突的函式或類的名稱,於是你就能直接使用cin cout而不必用std::cin來說明你這裡的cin是std裡面的。總之,通過命名空間就能有效的說明某個函式或類到底是呼叫了屬於**的庫。

可是,這樣做帶來了乙個新的問題,c++發展了那麼多年(直到2023年推出命名空間,大約發展了16年),現存的**已經有一定的量了,你突然給我搞了乙個命名空間,以前可沒這東西,我以前寫的**就不能再新的編譯器下執行了,這可不行。

於是,人們想出了乙個辦法。為包裝了std的那部分標準庫構件建立出新頭檔名。並且把新的標頭檔案名字取和舊標頭檔案相同,但不加字尾.h。所以變成了新版標頭檔案,變成了,而新舊標頭檔案的功能基本上相同的(但不完全相同),所以使用時,想要呼叫裡面的函式,就得使用類似std::cin的方法來說明cin是使用標準庫裡面的函式,而不是自己定義或別的廠商的庫的函式,當然,如前文所述,也可以在開頭使用using namespace std;來說明以下程式將使用標準庫的函式。

當使用時,使用的是全域性命名空間,也就是早期的c++實現(c++標準已經明確表示不支援這種用法了,所以理論上來說這種用法是非法的,但編譯器廠商有可能還支援這種用法)

當使用時,該標頭檔案沒有定義全域性命名空間,必須使用命名空間 std來說明你所使用的函式或類是來自iostream的

而c++對待c標頭檔案(c++可以使用c的標頭檔案)的方式是繼續支援舊的標頭檔案的支援,也既這種用法,以保持對c的相容性。但為了與時俱進(因為命名空間是個好東西呀),任然對應舊版標頭檔案開發了新版的標頭檔案,命名方式是,在每個舊版名字前新增乙個c。所以c的標頭檔案變成了新版c++的,c的標頭檔案變成了新版c++的。這也是為什麼c++**裡面有的標頭檔案加.h,有的不加.h的原因。#include進來可能是(1)、新版c++標頭檔案,如#include(2)、新版c語言標頭檔案,如#include(3)舊版的c標頭檔案,如#include(4)、舊版c++標頭檔案,理論上來c++是不支援這個用法了,但一些編譯器廠商任然可以這樣使用

回到開頭的那個問題,#include之後,是不能直接呼叫裡面的函式的,因為這個標頭檔案屬於c++標準庫的一部分,既cin這個函式屬於標準庫的乙個函式,如上文所述,它的用法是在函式名字放在了命名空間std中,你得用std::cin來說明一下這裡的cin是來自命名空間std裡面的,也就是標準庫裡面的cin函式,而不是別的庫的cin函式。這是c++的用法,不要與c混淆。

總結概括:庫的**性的發展導致經常出現命名重複,從而提出了命名空間的概念,有效地說明同個名稱的函式到底來自哪個庫,但這導致過去幾年所開發出來的**可能不能使用,從而c++委員會對應舊版標頭檔案重新開發了新版的標頭檔案,命名方式相同,但不新增字尾.h。委員會對待c語言標頭檔案的方式類似,重新開發了一套標頭檔案,命名方式是在標頭檔案開頭加上字母c,並去掉字尾.h.

新版c++對待舊版c++和舊版c語言的方式差別在於,明確提出不再支援c++標頭檔案.h的使用,但任然支援c語言標頭檔案.h的使用。這也是為什麼現在的c++**有的使用了.h,(呼叫了舊版c語言標頭檔案),也可能不加.h(使用新版標頭檔案)。

什麼是命名空間

c 中引入命名空間的主要是為了處理程式中常見的命名衝突,它是由ansi c 引入的可以由使用者命名的作用域。所謂命名空間,實際上就是乙個由程式設計者命名的記憶體區域 程式設計者可以根據需要指定一些有名字的空間域,把一些全域性實體分別放在各個命名空間中,從而與其它全域性實體分隔開來。如 namespa...

什麼是php命名空間

php命名空間是在5.3版本後加入的,命名空間反過來就是空間命名,在這裡的空間命名就像window下的資料夾命名,命名空間用關鍵字namespace來定義。在這裡用資料夾舉三個例子,比如相對於test資料夾下面的home.txt檔案,他相對於資料夾的路徑是 test home.txt,當前檔案下他的...

C 基礎 什麼是命名空間

命名空間是類的邏輯分組,它組織成乙個層次結構 邏輯樹。這個樹的根是system。名字空間是為了防止名字汙染在標準c 中引入的。它可以將其中定義的名字隱藏起來,不同的名字空間中可以有相同的名字而互不干擾,使用時用域操作符 來引用。namespace 名字 在應用的時候 使用這些資料和函式名稱太麻煩 給...