1. 程式人生 > >Learning C++ 之1.8a 命名衝突和std空間

Learning C++ 之1.8a 命名衝突和std空間

假如你第一次開車去你朋友家,朋友給了你一個地址:205 Front Streat in Mill City。直到到了Mill City,你開啟地圖發現有兩個205 Front Streat,這個時候就不知道到哪裡去了。除非有一些其他的資訊來幫你輔助定位。因此你需要打電話給你的朋友問一些詳細的資訊。因為這樣經常會引起歧義,所以一般在一個城市裡,不會有兩條重名的路。

通常來說,C++要求識別符號不能有歧義。如果兩個在同一個程式中的名字識別符號是相同的,那麼程式編譯器會上報error,通常叫做命名衝突錯誤。

一個命名衝突的例子:

a.cpp

#include <iostream>
 
void doSomething(int x)
{
    std::cout << x;
}

b.cpp

#include <iostream>
 
void doSomething(int x)
{
    std::cout << x * 2;
}

main.cpp

void doSomething(int x); // forward declaration for doSomething
 
int main()
{
    doSomething(5);
 
    return 0;
}

a.cpp和main.cpp,或者b.cpp和main.cpp單獨編譯都不會出現問題。但是假如這三個檔案在一個專案中,就會出現命名衝突的問題。

大多數命名衝突發生在兩個案例中:

1.兩個有相同函式名的檔案載入到了一個專案中

2.一個程式碼檔案中包含一個頭檔案,標頭檔案中的識別符號和其他檔案衝突(後面我們會討論標頭檔案)

伴隨著程式越來越大,我們的識別符號重名的概率會越來越高。好訊息是C++提供了大量的工具來避免這種錯誤。如區域性範圍,在區域性範圍內識別符號才有效,因此區域性範圍外可以重名。名稱空間,後面會詳細介紹。

名稱空間:

C++最初設計的時候,所有C++識別符號都可以直接使用如Cout,cin等,這也就意味著所有的C++定義的識別符號和你自己明明的識別符號可能會重名。當你inlude一個標準庫的標頭檔案的時候,程式碼會突然報命名衝突的錯誤。或者程式碼在之後的升級版本中會有衝突,所以C++把所有標準庫裡的函式功能移植到了一個叫做名稱空間的地方。

就像一個城市確保自己的道路都是唯一的一樣,名稱空間保證了C++的識別符號在該名稱空間裡是唯一的。這就放置了名稱空間裡的識別符號發生重新命名的問題。

就像std::cout的真正的名字並不是std::cout,而是cout,std是該識別符號的名稱空間的名字。C++標準庫中的所有功能性表示都命名在std空間裡,這樣我們就不用擔心我們自己的識別符號命名和標準庫裡的命名衝突了。

關於名稱空間的問題我們會在後面詳細介紹,並教你怎麼建立自己的名稱空間。現在你只需要知道std::cout指的是C++標準函式中的庫的名稱空間就可以了。我們需要告訴編譯器識別符號在哪個名稱空間裡。

顯示的使用名稱空間:

最直接的使用名稱空間的方式就是在識別符號前加上字首如:

   std::cout << "Hello world!";
這是最安全的方式,因為使用起來沒有歧義。C++提供了其他方式來使用名稱空間,這個會在4.3C 使用宣告中介紹