什么是命名空间 为什么C++需要使用命名空间
引言:
問題:學習過C,然后再學c++的人可能會這么問,我#include<iostream>之后,不就是把頭文件拉進來了嗎,而cin cout等函數不就是iostream.h里面的函數嗎,我使用cin cout時,編譯器為什么會說? “Error 未定義標示符”呢?
解決方法:這樣寫
但可能不知道為什么加這句
我剛學C++時也不明白為什么,看課本解釋說什么命名空間的,看不明白,只是知道這樣寫才能通過編譯,也沒有深究,每次都默默加上去的說。
現在,任然是個菜鳥的說,看了一些資料之后,寫了這篇筆記“關于using namespace std;以及為什么有的頭文件需要加上.h而有的頭文件不需要”,可能不夠嚴謹,歡迎指出錯誤。
這是個歷史問題。
一、從庫的概念說起
這得從庫的概念說起,你#include進去的就是別人幫你寫好的庫,你可以直接調用頭文件里面封裝好的函數或類,比如你用的cin cout等就是c++標準庫里面的函數,這樣你就不用自己寫一個函數cin 來實現輸入功能,也不用寫函數cout來實現輸出功能,直接調用就可以了。除了C++標準庫,一些公司封裝了一些函數,實現某些強大的功能,然后拿來賣,比如微軟的MFC ,Trolltech公司的Qt等,所以c++變得更加強大,不僅可以直接調用標準庫,還能調用別的公司封裝好的庫。
二、命名空間誕生的原因
早期的c++庫內容有限,可隨著時間的推移,庫的功能越來越強大,每個廠商之間可能將庫里面的函數或類取了相同的名字,比如說A公司的庫就可能定義了一個叫做sum的函數,而B公司也定義一個叫做sum的函數,于是就出現問題了,程序員開發時,如果同時使用了A的庫,又使用了B公司的庫,那么就可能出現混亂,你調用的sum到底是哪家公司的。最初,人們就想了個辦法,廠商將名字取得更長更復雜來避免重復,可這樣做卻給編寫和閱讀帶來了困難。后來,人們創造了命名空間這個概念(1998年),它能有效地指出某個標示符到底屬于哪個庫。
三、什么是命名空間
通過使用 namespace xxx;來說明你所用的這個函數或類來自于哪個庫或者是自己寫的函數。例如,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++發展了那么多年(直到1998年推出命名空間,大約發展了16年),現存的代碼已經有一定的量了,你突然給我搞了一個命名空間,以前可沒這東西,我以前寫的代碼就不能再新的編譯器下運行了,這可不行。
于是,人們想出了一個辦法。為包裝了std的那部分標準庫構件創建出新頭文件名。并且把新的頭文件名字取和舊頭文件相同,但不加后綴.h。所以<iostream.h>變成了新版頭文件<iostream>,<complex.h>變成了<complex>,而新舊頭文件的功能基本上相同的(但不完全相同),所以使用<iostream>時,想要調用里面的函數,就得使用類似std::cin的方法來說明cin是使用標準庫里面的函數,而不是自己定義或別的廠商的庫的函數,當然,如前文所述,也可以在開頭使用using namespace std;來說明以下程序將使用標準庫的函數。
當使用<iostream.h>時,使用的是全局命名空間,也就是早期的c++實現(c++標準已經明確表示不支持這種用法了,所以理論上來說這種用法是非法的,但編譯器廠商有可能還支持這種用法)
當使用<iostream>時,該頭文件沒有定義全局命名空間,必須使用命名空間 std來說明你所使用的函數或類是來自iostream的
而c++對待C頭文件(c++可以使用c的頭文件)的方式是繼續支持舊的頭文件的支持,也既<string.h>這種用法,以保持對C的兼容性。但為了與時俱進(因為命名空間是個好東西呀),任然對應舊版頭文件開發了新版的頭文件,命名方式是,在每個舊版名字前添加一個c。所以C的頭文件<string.h>變成了新版c++的<cstring>,C的頭文件<stdio.h>變成了新版c++的<cstdio>。這也是為什么c++代碼里面有的頭文件加.h,有的不加.h的原因。#include進來可能是(1)、新版C++頭文件,如#include<iostream>(2)、新版C語言頭文件,如#include<cstring>(3)舊版的C頭文件,如#include<string.h> (4)、舊版C++頭文件,理論上來C++是不支持這個用法了,但一些編譯器廠商任然可以這樣使用
五、完結
回到開頭的那個問題,#include<iostream>之后,是不能直接調用里面的函數的,因為<iostream>這個頭文件屬于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(使用新版頭文件)。
?
————————————————
版權聲明:本文為CSDN博主「買柴火的小火柴」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013162593/article/details/22823425
總結
以上是生活随笔為你收集整理的什么是命名空间 为什么C++需要使用命名空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓的闪付功能怎么设置(安卓的闪付)
- 下一篇: C++谷歌命名规范