C++ using namespace
參考:http://en.cppreference.com/w/cpp/language/namespace#Using-directives
1 #include <stdio.h> 2 3 namespace A{ 4 struct S{ 5 S(){ 6 printf("A::S(int) called \n"); 7 } 8 }; 9 } 10 11 namespace B{ 12 struct S{ 13 S(){ 14 printf("B::S(int) called \n"); 15 } 16 }; 17 using namespace A; 18 S s; 19 } 20 21 int main() 22 { 23 using namespace B; 24 S s; 25 }第23行講述了using-directive(以下簡(jiǎn)稱U.D.)的第一個(gè)效應(yīng):把B名字空間虛擬的引入22行和25行包裹的塊(block)。當(dāng)?shù)?4行,遇到S這個(gè)符號(hào)時(shí),B::S也是候選者,所以,程序員節(jié)省了幾個(gè)打字(B::S).
但是編譯失敗,因?yàn)?7行,在B塊中,引入了A名字空間。因此,第24行名字解析時(shí),會(huì)遇到兩個(gè)候選者:A::S 和 B::S。
第18行講述了U.D.的第二個(gè)效應(yīng),當(dāng)本塊的名字和其它名字沖突時(shí),編譯器不報(bào)錯(cuò),會(huì)選擇本塊的名字(就是第12行定義的S)。按此思路,可以修改上述編譯失敗的代碼為:
#include <stdio.h>namespace A{struct S{S(){printf("A::S(int) called \n");}}; }namespace B{struct S{S(){printf("B::S(int) called \n");}};using namespace A;S s; }int main() {struct S{S(){printf("main::S(int) called \n");}};using namespace B;S s; }這意味著什么?一個(gè)unqualified name(例如:S s; 而不是A::S s;)會(huì)隨著工程的龐大,有時(shí)會(huì)編譯失敗,有時(shí)會(huì)改變含義。難以管理,這是很多編程規(guī)范中,不建議using namespace std;放到頭文件的原因。
局部使用只影響局部,所以不能一概否定U.D. 例如:
1 #include <stdio.h> 2 3 namespace A{ 4 struct S{ 5 S(){ 6 printf("A::S(int) called \n"); 7 } 8 }; 9 } 10 11 namespace B{ 12 struct S{ 13 S(){ 14 printf("B::S(int) called \n"); 15 } 16 }; 17 } 18 19 int main() 20 { 21 { 22 using namespace B; 23 S s; 24 } 25 26 { 27 using namespace A; 28 S s; 29 } 30 }第23行和第28行,只收到本塊的U.D的影響。所以局部簡(jiǎn)單代碼應(yīng)允許使用U.D.以簡(jiǎn)化代碼:
1 { 2 std::cout << std::hex << 100 << std::endl; 3 } 4 5 { 6 using namespace std; 7 cout << hex << 100 << endl; 8 } 9 10 { 11 using std::cout; 12 using std::hex; 13 using std::endl; 14 cout << hex << 100 << endl; 15 }哪一個(gè)您更喜歡呢?顯然在這個(gè)場(chǎng)合,沒人用using-declare吧?
using namespace xxx;在名字查找時(shí),提供一個(gè)類似額外搜索路徑的機(jī)制。當(dāng)主路徑?jīng)]有找到名字時(shí),才考慮這個(gè)額外搜索路徑。例如:
1 #include <iostream> 2 3 namespace Outer{ 4 5 int i=100; 6 7 } 8 9 int main(){ 10 11 int i=20; 12 { 13 using namespace Outer; 14 i=0; 15 } 16 17 std::cout << "Outer::i=" << Outer::i; 18 }第14行,因?yàn)樵谥魉阉髀窂缴蟟可以找到,就是第11行的int i=20; 因此i沒有歧義。主搜索路徑,就是一些嵌套的大括號(hào)構(gòu)成的包裹關(guān)系路徑。
1 #include <iostream> 2 3 namespace Outer{ 4 int i=100; 5 } 6 7 namespace KK{ 8 int i=200; 9 } 10 11 namespace { 12 int i=300; 13 } 14 15 int main(){ 16 using namespace KK; 17 { 18 using namespace Outer; 19 i=0; 20 } 21 }第19行的i;我們?cè)谥魉阉髀窂缴先四X搜索一下,就是17~20行為第一層,15~21行為第二層,都找不到i的定義。這時(shí)候using namespace引入的輔助搜索路徑被考了。會(huì)發(fā)現(xiàn)有三個(gè)名字空間的i;
匿名名字空間的i,? ?KK::i,? Outer::i? 。編譯器會(huì)報(bào)錯(cuò),抱怨候選者太多,請(qǐng)程序員明確指示用哪一個(gè)。如果using namespace被放到頭文件里,還需要人腦做#include展開,所以帶給程序員的負(fù)擔(dān)是比較大的。所以,應(yīng)嚴(yán)格控制using namespace的作用范圍。
總結(jié):建議在最內(nèi)層的塊內(nèi)使用using namespace,就是第18行的樣子。謹(jǐn)慎在外層塊(第16行)使用,禁止在文件的作用域(包括頭文件)使用using namespace?
轉(zhuǎn)載于:https://www.cnblogs.com/thomas76/p/8657133.html
總結(jié)
以上是生活随笔為你收集整理的C++ using namespace的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决Intellij IDEA部署Jav
- 下一篇: LinkedList源码分析(基于Jav