namespace & using

命名空間(namespace)是爲了避免可能遇到的名字衝突而設計的。一個命名空間是一個作用域,通過命名空間內部定義庫中的名字,庫的作者(以及用戶)可以避免全局名字固有的限制。命名空間的語法形如:
  1. namespace space_name {
  2.    ...  //可以出現在全局作用域的任意聲明,包括可以是其他命名空間
  3. }
1.每個命名空間是一個作用域。命名空間內部出現的名字必須唯一,但不同命名空間中可以具有同名成員。命名空間外部的代碼必須指出名字定義在哪個命名空間中,或者使用using聲明指出。
2.從命名空間外部使用命名空間成員。如下A和B兩種方式,其它簡化訪問的方法稍後討論。
  1. namespace cpp_primer {
  2.    class Query{
  3.       ...
  4.    };
  5. }

  6. cpp_primer::Query q = cpp_primer::Query("hello");  //A

  7. using cpp_primer::Query;
  8. Query q = Query("hello");  //B
3.命名空間可以是不連續的。意思是說命名空間是累積的,可以出現在很多不同的文件中。即一個namespace定義既可以是定義一個全新的命名空間,也可以是向一個已經存在的命名空間中添加內容。值得注意的是,名字只在聲明名字的文件中可見,即在一個文件中聲明的名字,對於位於不同文件中的同一個命名空間,也不是立即可見的,在其他文件中仍然需要聲明該名字。
4.接口和實現分離。可以使用頭文件和實現文件來組織命名空間。
5.定義命名空間成員。在命名空間內部定義和外部定義兩種方式形如:
  1. //內部定義方式
  2. namespace cpp_primer {
  3.    class SalesItem {
  4.       // ...
  5.    };
  6.    std::istream&
  7.    operator>>(std::istream& in, SalesItem& s) {
  8.       // ...
  9.    }
  10. }

  11. //外部定義方式
  12. cpp_primer::SalesItem
  13. cpp_primer::operator+(const SalesItem& lhs, const SalesItem& rhs) {
  14.    SalesItem ret(lhs);
  15.    // ...
  16. }
注意到外部定義方式,返回類型和函數名由命名空間名字限定。一旦看到完全限定的函數名,就處於命名空間的作用域中。因此,形參表和函數體中就不需要再使用完全限定的名字來使用某個成員了。
6.不能在不相關的命名空間中定義成員。例如函數cpp_primer::operator+()可以在cpp_primer命名空間中定義,也可以使用限定形式在全局作用域中定義。但是不能定義到另一個無關的命名空間內部。
7.關於全局命名空間。如果沒有限定,定義在全局作用域的名字就是定義在全局空間中的。全局命名空間沒有名字,所以使用::member_name來引用全局命名空間的成員。
8.嵌套命名空間。是一種層次結構,例如:
  1. namespace A {
  2.    namespace B {
  3.       class Something {
  4.          // ...
  5.       };
  6.    }
  7. }
則完全限定的名字是A::B::Something
9.未命名的命名空間。命名空間可以是未命名的,未命名的命名空間在定義時沒有給定名字。
  1. namespace {
  2.    int i;
  3. }
未命名的命名空間的定義局部於特定文件,每個文件有自己的未命名的命名空間。從這點來說,其功能與static(文件靜態)的作用一致。但是在C++語境中,建議用未命名的名字空間來取代文件中的靜態聲明。未命名的名字空間也可以是嵌套的。總體來說,定義於未命名的名字空間內部的成員,使用時相對於有名字的命名空間內的成員要提升一級。
10.命名空間的別名。可以用命名空間別名將較短的同義詞與命名空間名字相關聯。例如:
  1. namespace an_example_namespace {
  2.    // ...
  3. }
  4.  
  5. namespace aens = an_example_namespace;
11.using指示。using指示不同於using聲明。using聲明只是將某個特定成員引入到可見狀態;而using指示則是將整個命名空間的所有成員引入到當前作用域。
  1. using namespace std;
在實際應用中需要避免使用using指示,因爲這種方式可能會重新引入名字衝突的所有問題。

參考:
C++ Primer中文版(第四版)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章