大型程序一般都是分為多個模塊,由多人協作來進行開發的,其中還不可避免的會用到庫。而各個模塊代碼以及庫中會定義大量變量,而大量變量的命名,不可避免的會遇見“重名”的問題。“重名”的情況我們稱之為命名空間污染。就像你的同學重名了(這也是沒有辦法的事),比如同班有兩個李明(此名重名率極高),這個時候當你們提到其中某一個時,聆聽者就搞不懂到底說的是哪個李明了,這個時候就出現了命名空間污染。而這個時候,命名空間就派上用場了,而所謂的命名空間事實上就相當於給作用域起了一個名字,然後你可以在這個作用域中進行各種聲明和定義。命名空間的定義如下:
1 namespace my_namespace { //關鍵字namespace 命名空間名字 2 int my_test; // 各種聲明和定義 3 namespace son_namespace { /*....*/ } //嵌套命名空間 4 };
只要是能在全局作用域中的聲明就能放在命名空間中,包括:類,變量(及其初始化),函數(及其定義)、模板和其他命名空間。
命名空間可以是不連續的。我們可以打開一個已經定義過的命名空間,並在其中添加新的聲明與定義。
namespace my_namespace { int my_index; //打開一個已經定義過的命名空間 }//注意此處沒有分號!!!
值得注意的是,通常情況下不要將#include <***>放在命名空間中,這樣的話等於我們試圖將頭文件中的命名空間嵌套在我們定義的命名空間中,程序普遍會出錯,所以建議避免此種情況的發生。
命名空間的成員在命名空間中可以正常使用,而在命名空間外則需要加上前綴。就比如兩個李明一個家是山西太原的,另一個家是陝西西安的,這個時候你就可以說:陝西西安的那個李明如何如何,這樣別人就不會出現搞不清楚對象的情況。
my_namespace::my_test = 5;
但是大型項目中變量何其多,這樣每個都加前綴會給巨大的不必要的麻煩。所以C++提供了命名空間別名、using聲明以及using指示來解決此問題。
命名空間別名其實與類型別名是一樣的,它可以讓我們為我們定義的命名空間設定一個短的多的同義詞,這樣可以減輕一點工作量。就比如說你覺著每次都加說陝西西安覺著累,然後你可以告訴聆聽者一聲,說:說這個太累,後面我就直接說陝西的李明,這樣好點。
namespace my_ns = my_namespace;
命名空間別名也可以指向一個嵌套的空間。
namespace son_ns = my_namespace::son_namespace;
using聲明的作用與其他聲明一致,一條using聲明語句一次只引入命名空間的一個成員,它的有效范圍從聲明開始到聲明所在的作用域結束為止。再回到剛才那個例子,這次在談話之前就告訴聆聽者:我先聲明我說的是咱班陝西西安的那個李明,然後在這次談話中你說李明他自然知道你說的是哪個了。
1 using my_namespace::my_test; 2 int 3 main(void) 4 { 5 my_test = 10; 6 }
using指示則是將命名空間的所有成員都呈現到當前作用域。就比如告訴聆聽者:我接下來說的人都是陝西西安的。
1 using my_namespace; 2 3 int 4 main(void) 5 { 6 my_test = 10; 7 my_index = 100; 8 }
我個人建議謹慎使用using指示,因為和using聲明不同,我們無法控制成員的可見與否,因為所有的都是可見的,如果兩個using指示的命名空間中有同樣名稱的成員,則又會出現命名空間污染的情況。
模板特例化必須定義在原始模板所屬的命名空間。
全局命名空間以隱式的方式聲明,全局作用域中的定義也就定義在全局命名空間。
::someone; //表示全局命名空間中的一個成員
內聯命名空間(C++11新標准) ,它的特殊之處在於,內聯命名空間中的名字可以被外層命名空間直接使用,無需添加前綴。
inline namespace test { /*此命名空間即為內聯命名空間*/ };
這個特性對於代碼版本升級且需保留舊版本代碼的情況來說實在是太有用了。
namespace work { namespace edition1 { /*初始版本代碼*/ }; inline namespace edition2 { /*新版本代碼*/ }; };
當我們更新代碼以及新代碼出現故障緊急回撤版本時,只需要增刪inline即可,只要保證接口不變,則可以實現無縫更換。
未命名的命名空間,是指namespace後沒有自己定義的名字的命名空間。
namespace { /*這是一個未命名的命名空間*/ };
未命名的命名空間中定義的變量擁有靜態的生命周期,它們在第一次使用前創建,知道程序結束時才銷毀。
它的作用與C語言中的static一致。