C++筆記(三)——名稱空間
定義和使用名稱空間
在一個應用程式的多個檔案中可能會存在同名的全域性物件,這樣會導致應用程式的連結錯誤。使用名稱空間是消除命名衝突的最佳方式。
名稱空間的定義格式為:
namespace 名稱 { 常量、變數、函式等物件的定義 } |
1. 如果使用名稱空間中的物件,需要在物件前使用名稱空間名作為字首。
2. 如果需要訪問同一個名稱空間中的多個物件,可以使用using命令引用整個名稱空間物件,這樣就不必在每個物件前新增名稱空間字首了。
3. using命名的作用域從當前引用處到當前作用域的結束。如果將
4. 如果在函式中定義的區域性變數與名稱空間中的變數同名時,名稱空間中的變數被隱藏。
5. 對於同一個名稱空間,可以在多個檔案中定義。
對於一個存在著標準輸入輸出的C++控制檯程式,一般會在#include <iostream>的下一行發現一句話,using namespace std。這句話其實就表示了所有的標準庫函式都在標準名稱空間std中進行了定義。其作用就在於避免發生重新命名的問題。
1. 關於namespace
C++引入了名稱空間namespace主要解決了多個程式設計師在編寫同一個專案中可能出現的函式等重名的現象。解決方法就是加上自己的名稱空間。比如下面的例子:
#include <iostream> using namespace std; namespace ZhangSan { int a=10; //張三把10賦值給了變數a } namespace LiSi { int a=5; //李四把10賦值給了變數a } void main() { int a=1; cout<<"張三定義的a="<<ZhangSan::a<<endl; cout<<"李四定義的a="<<LiSi::a<<endl; cout<<"主函式定義的a="<<a<<endl; }
上例中的“ZhangSan::a”和“LiSi::a”分別表示了呼叫張三名稱空間中的a變數和李四名稱空間中的a變數。這樣的好處顯而易見,那就是雖然張三和李四這兩個程式設計師都定義了一個變數a,但是並不會出現重名的危險。
執行結果為:
2. 關於using namespace *
顧名思義,using namespace * 就表示釋放名稱空間* 中間的東西。好處在於我們在程式裡面就不用在每個函式的頭上都加上*::來呼叫。比如說如果上面那個程式,如果我們不在using namespace std,那麼我們就需要在主函式中的標準輸出流cout函式前面加上std,寫成
std::cout
表示呼叫std空間裡面的標準輸出流cout。但是有些時候我們也不能圖這個方便,比如說如果在主函式中將名稱空間ZhangSan和LiSi的中所定義的變數釋放出來,如下例1:
#include <iostream>
using namespace std;
namespace ZhangSan
{
int a=10; //張三把10賦值給了變數a
}
namespace LiSi
{
int a=5; //李四把10賦值給了變數a
}
void main()
{
int a=1;
using namespace ZhangSan;
using namespace LiSi;
cout<<a<<endl;
}
這個程式輸出結果為:
如果我們在主函式中把 int a=1給刪除,如下例2:
#include <iostream>
using namespace std;
namespace ZhangSan
{
int a=10; //張三把10賦值給了變數a
}
namespace LiSi
{
int a=5; //李四把10賦值給了變數a
}
void main()
{
using namespace ZhangSan;
using namespace LiSi;
cout<<a<<endl;
}
會發現根本就不會通過編譯,輸出的錯誤資訊為:
error C2872: “a”: 不明確的符號
分析可以看出,上面這個例2會引起歧義。因為ZhangSan中間的a被釋放出來,同理LiSi中間的a也被釋放出來了。那麼編譯器就不知道到底哪個才是需要輸出的a,自然就會引起歧義了。同理,在例1中,編譯器同樣不知道到底哪個才是需要輸出的a,於是它只採用了主函式中自己定義的a,這樣程式也不會報錯,但是隻會輸出1,自然結果就如上面的圖所示了。