看到網上很多人寫了namespace的使用方法,我在此對大家的進行簡單總結。通過此日志,可以快速掌握namespace的原理以及用法。
關於C++ namespace,我們需要回答如下幾個問題:
1、什麼是namespace?
2、為什麼有namespace?也就是namespace的作用
3、namespace的使用方法有哪些?
(一)什麼是namespace?
首先我們看看C++標准規范中對namespace的定義如下:
named-namespace-definition:
namespace identifier { namespace-body }
unnamed-namespace-definition:
namespace { namespace-body }
namespace包含兩種,一種是有名的命名空間,一種是無名的命名空間。我們先看如下兩個實例:
//有名的namespace的使用方法 #includenamespace named_namespace{ //變量 int value = 1; //函數 void Output() { std::cout << value << std::endl;} //結構體 struct Test{ int value; void Output() {std::cout << value << std::endl;} }; //類 class Object{ public: void SetValue(const int& val){ value_ = val; } void Output() {std::cout << value_ << std::endl;} private: int value_; }; }
上面是有名的命名空間的使用方式,可以看出來,命名空間可以包含變量、函數、結構體以及類等,統統將他們包含進來。
上述是無命名空間的使用方式。只不過無命名空間是沒有名字的。
(二)為什麼有namespace?也就是namespace的作用
第一部分,我們講述了namespace的具體定義形式,但是我們為什麼要使用namespace呢?namespace能給我們實際變成過程中帶來哪些好處呢?
namespace主要用於解決“命名沖突”問題。在大型項目開發中,可能有很多人同時進行編寫代碼,不同的模塊可能使用了相同的全局變量,當系統集成的時候,就會發生命名沖突的問題。我們通過如下簡單代碼可以明白什麼是命名沖突:
頭文件head1.h定義如下:
int value = 1;
頭文件head2.h定義如下:
double value = 2.2;
主函數定義如下:
#include#include head1.h #include head2.h int main(int argc, char** argv) { std::cout << value << std::endl; return 0; }
編譯錯誤信息如下:
從上面代碼可以看出,value出現在兩個頭文件中進行定義了,主函數main中value發生了沖突,不能確定是哪一個頭文件中的。上述只是一個簡單的示例,當面對成百上千的頭文件時候,很難避免相同名字的出現。
此時,namespace的作用就顯現出來了,namespace是“命名空間”,從名字上就可以看出來,就是構成了一個空間,在空間裡面的內容和空間外的內容無關,只和本空間內部的信息有關。簡單點講就是,namespace用於分割項目整個空間,使每一個空間相對獨立,雖然相同的名字存在,但是他們處於不同的namespace中,就不會發生命名沖突。
上述發生錯誤的代碼可以通過namespace進行解決:
頭文件head1.h定義如下:
namespace head1{ int value = 1; }
頭文件head2.h定義如下:
namespace head2{ double value = 2.2; }
主函數定義如下:
#include#include head1.h #include head2.h int main(int argc, char** argv) { std::cout << head1::value << std::endl; std::cout << head2::value << std::endl; return 0; }
運行結果如下:1 和 2.2
上面著重講述了有名namespace的作用。
其實無名namespace的作用也是避免“命名沖突”。關於無命名空間,需要注意如下兩點:
1、無名名字空間主要是保持代碼的局部性
2、在C++編譯器實現時,無名名字空間其實是有名字的,這個隱含的名字跟它所在編譯單元名字相關。所以基於這一點,我們不能跨編譯單元使用無名名字空間中的名字
(三)namespace的使用方法有哪些?
主要的使用方法有兩種,一種是名字::XXX,第二種是using關鍵字。
第一種在上述的代碼中已經進行過相應的演示。
第二種代碼類似於using namespace std;這種方式,下面直接使用std空間裡面的內容即可。雖然這種方式簡單快捷,但是會有隱形的危險在代碼裡面,當兩個不同的命名空間同時在一個文件中使用using 方式,相同名字就會發生沖突。