1. 程式人生 > >關於using namespace std;的淺談

關於using namespace std;的淺談

《C++ Primer Plus (第六版 中文版 人民郵電出版社)》第九章:記憶體模型和名稱空間 第328頁:
"有關using編譯命令和using宣告,需要記住的一點是,他們增加了名稱衝突的可能性。"

《C++ Primer Plus (第六版 中文版 人民郵電出版社)》第九章:記憶體模型和名稱空間 第329頁:
一般說來,使用using命令使用using編譯命令安全,這是由於它只匯入了制定的名稱。如果該名稱與區域性名稱發生衝突,編譯器將發出指示。using編譯命令匯入所有的名稱,包括可能並不需要的名稱。如果與區域性名稱發生衝突,則區域性名稱將覆蓋名稱空間版本,而編譯器並不會發出警告。另外,名稱空間的開放性意味著名稱空間的名稱可能分散在多個地方,這使得難以準確知道添加了哪些名稱。
...
然而名稱空間的支持者希望有更多的選擇,既可以使用解析運算子面也可以使用using宣告,也就是說,不要這樣做:
using
namespace std; // avoid as too indiscriminate(隨意)
而應這樣做
int x;
std::cin >> x ;
std::cout << x << std::endl;
或者這樣做
using std::cin;
using std::cout;
using std::endl;
int x;
cin >> x;
cout << x << endl;

《C++ Primer Plus (第六版 中文版 人民郵電出版社)》附錄I: 轉換為ISO標準的C++ 第915頁:
名稱空間有助於組織程式中使用識別符號,避免名稱衝突。由於標準庫是使用性的標頭檔案組織實現的,它將名稱放在std名稱空間中,因此使用這些標頭檔案需要處理名稱空間。
出於簡化的目的,本書的事例通常使用編譯命令using來使std名稱空間中名稱可用:
#include <iostream>
#include <string> #include <vector> using namespace std; //a using-directive
然而,不管需要於否,都匯出名稱空間中的所有名稱,是於名稱空間的初衷背道而馳的

那麼由此看來,隨意使用using namespace std;這句話是不安全的,只是為了圖方便,但是,我們在學習了很長時間的c++後,最好還是不要使用這句話!!!
因為在比較大的專案中會造成一系列的命名重複問題,下面引用一個例子。
#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,自然結果就如上面的圖所示了。(參考自http://www.cnblogs.com/uniqueliu/archive/2011/07/10/2102238.html)