天天看點

[C++再學習系列] Using聲明和指令的工作原理

 對于C++編譯器,那些名字可見至關重要,太多的名字可見将導緻名字查找效率的降低,而名字太少将導緻無法找到所需類型或函數的名字,進而導緻編譯錯誤。除了最常用的include可以導入可見名字之外,using關鍵字也可以導入名字到特定的編譯單元中(單個cpp檔案)。

差別:

Using聲明: usingnamespace std; -- 導入某個名字空間可見的名字實體

Using指令: using N::Widget; -- 導入特定名字

  Using用于導入特定名字空間下的名字實體,可以是全部名字實體(usingnamespace std;),也可以是特定的名字實體(using std::map;)。

  工作原理:using聲明将擷取的是在遇到using聲明瞬間所見到的名字空間中的實體。這點是可以了解的,這樣的工作方式有利于避免名字沖突(過多導緻污染),加快名字查找過程。但這同時意味着:隻有在using namespace std;語句之前所include的std頭檔案的名字實體被引入,即using并未引入所有來自std的名字實體。

  Using關鍵字定理:絕對不要在include之前使用using聲明或指令。

  推論:不要在頭檔案中使用using聲明或指令,相反應該使用名字空間限定所有的名字,尤其是來自其他名字空間的名字。(原因:1)頭檔案并不知道完全的include資訊,頭檔案總是被用于其他cpp中,其後總會出現另外的include; 2)避免不必要的名字污染)

  例子:

// snippet 1

namespace A {

 int f(double);

}

// snippet 2

namespace B {

  using A::f;

  void g();

// snippet 3

 int f(int);

// snippet 4

void B::g() {

  f(1);                         // which overload iscalled?

  這幾個檔案先後出現順序将決定f(1)是否可編譯(所有的f函數定義均不可見)?以及重載哪個函數(哪些函數可見,并參與重載)。

  錯誤地使用using将導緻名字空間污染,或錯誤地導入不完整的名字空間的瞬間快照(導緻無法找到特定名字實體)。在頭檔案中,使用using将使這個問題更加嚴重(多處使用,使用順序不可控)。

  例外:編寫類成員級的using聲明導入所需的基類成員名字是一個合法技巧,隻有這樣才能避免基類的名字被屏蔽,如重載函數不可見問題。(見派生類的函數重載)

----------------------------------------------------

本文轉自 zhenjing 部落格園部落格,原文連結:http://www.cnblogs.com/zhenjing/archive/2010/11/04/1868891.html   ,如需轉載請自行聯系原作者

繼續閱讀