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(以下简称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 <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;
}

这意味着什么?一个unqualified name(例如:S s; 而不是A::S s;)会随着工程的庞大,有时会编译失败,有时会改变含义。难以管理,这是很多编程规范中,不建议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的影响。所以局部简单代码应允许使用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 <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行,因为在主搜索路径上i可以找到,就是第11行的int i=20; 因此i没有歧义。主搜索路径,就是一些嵌套的大括号构成的包裹关系路径。

 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;我们在主搜索路径上人脑搜索一下,就是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

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ using namespace

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/397524

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月11日 上午9:14
下一篇 2023年4月11日 上午9:14

相关推荐