博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ using namespace
阅读量:5833 次
发布时间:2019-06-18

本文共 2936 字,大约阅读时间需要 9 分钟。

参考:http://en.cppreference.com/w/cpp/language/namespace#Using-directives

1 #include 
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(以下简称U.D.)的第一个效应:把B名字空间虚拟的引入22行和25行包裹的块(block)。当第24行,遇到S这个符号时,B::S也是候选者,所以,程序员节省了几个打字(B::S).

但是编译失败,因为17行,在B块中,引入了A名字空间。因此,第24行名字解析时,会遇到两个候选者:A::S 和 B::S。

第18行讲述了U.D.的第二个效应,当本块的名字和其它名字冲突时,编译器不报错,会选择本块的名字(就是第12行定义的S)。按此思路,可以修改上述编译失败的代码为:

#include 
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;}

这意味着什么?一个unqualified name(例如:S s; 而不是A::S s;)会随着工程的庞大,有时会编译失败,有时会改变含义。难以管理,这是很多编程规范中,不建议using namespace std;放到头文件的原因。

局部使用只影响局部,所以不能一概否定U.D. 例如:

1 #include 
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的影响。所以局部简单代码应允许使用U.D.以简化代码:

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 }

哪一个您更喜欢呢?显然在这个场合,没人用using-declare吧?

using namespace xxx;在名字查找时,提供一个类似额外搜索路径的机制。当主路径没有找到名字时,才考虑这个额外搜索路径。例如:

1 #include 
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行,因为在主搜索路径上i可以找到,就是第11行的int i=20; 因此i没有歧义。主搜索路径,就是一些嵌套的大括号构成的包裹关系路径。

1 #include 
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;我们在主搜索路径上人脑搜索一下,就是17~20行为第一层,15~21行为第二层,都找不到i的定义。这时候using namespace引入的辅助搜索路径被考了。会发现有三个名字空间的i;

匿名名字空间的i,   KK::i,  Outer::i  。编译器会报错,抱怨候选者太多,请程序员明确指示用哪一个。如果using namespace被放到头文件里,还需要人脑做#include展开,所以带给程序员的负担是比较大的。所以,应严格控制using namespace的作用范围。

总结:建议在最内层的块内使用using namespace,就是第18行的样子。谨慎在外层块(第16行)使用,禁止在文件的作用域(包括头文件)使用using namespace 

转载于:https://www.cnblogs.com/thomas76/p/8657133.html

你可能感兴趣的文章
html5纲要,细谈HTML 5新增的元素
查看>>
Android应用集成支付宝接口的简化
查看>>
[分享]Ubuntu12.04安装基础教程(图文)
查看>>
django 目录结构修改
查看>>
win8 关闭防火墙
查看>>
CSS——(2)与标准流盒模型
查看>>
C#中的Marshal
查看>>
linux命令:ls
查看>>
Using RequireJS in AngularJS Applications
查看>>
【SAP HANA】关于SAP HANA中带层次结构的计算视图Cacultation View创建、激活状况下在系统中生成对象的研究...
查看>>
DevOps 前世今生 | mPaaS 线上直播 CodeHub #1 回顾
查看>>
iOS 解决UITabelView刷新闪动
查看>>
CentOS 7 装vim遇到的问题和解决方法
查看>>
JavaScript基础教程1-20160612
查看>>
【ros】Create a ROS package:package dependencies报错
查看>>
通过容器编排和服务网格来改进Java微服务的可测性
查看>>
使用《Deep Image Prior》来做图像复原
查看>>
Linux基础命令---rmdir
查看>>
Squid 反向代理服务器配置
查看>>
Java I/O操作
查看>>