为什么包括“使用命名空间”到头文件中一个坏主意在C ++? [英] Why is including "using namespace" into a header file a bad idea in C++?

查看:156
本文介绍了为什么包括“使用命名空间”到头文件中一个坏主意在C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读Bruce Eckel关于命名空间的C ++思考时,我遇到了以下语句:


请参阅
使用指令在头文件
(至少不在范围之外)。
的原因是使用指令
消除了该
特定命名空间的保护,以及效果
持续到当前
编译单元结束。如果你在
头文件中使用
指令(范围之外),这意味着
命名空间保护的这种损失将发生在
任何包含这个
标题,通常意味着其他标题
文件。


您是否愿意帮助我理解上面的语句有一些简单的例子?

解决方案

请考虑此计划:

  line#
1 #include< string>
2
3使用namespace std;
4
5 struct string {const char * p; }; //当心:另一个字符串!
6
7 int main()
8 {
9 string x; //错误:歧义 - 哪个字符串是想要的?
10}



如果您尝试编译它,您会看到错误: p>

  g ++ using.cc -o使用
使用.cc:在函数`int main()'中:
使用.cc:9:错误:使用`字符串'是不明确的
using.cc:5:错误:首先声明为`struct string'这里
/ usr / lib / gcc / i386-redhat- linux / 3.4.6 /../../../../ include / c ++ / 3.4.6 / bits / stringfwd.h:60:error:
也声明为`typedef struct std :: basic_string ; char,std :: char_traits< char>,std :: allocator< char> > std :: string'here
using.cc:9:error:`string'未在此范围内声明
using.cc:9:error:expected`;'beforex$ b $这里的问题是,当 main()指定



string x; ,编译器不确定用户定义 :: string 还是包含 std :: string



现在假设你选择程序的顶部...第1行到第5行 - struct string ...并将其放入一个头文件中,然后 #include 之前 main()。没有任何更改:您仍然有错误。因此,就像独立程序一样,使用在其中使用语句的头文件可能会对包含它们的其他代码造成麻烦,使它们的一些语句不明确。



这可能是一个更大的痛苦,因为头可以包括 - 直接或间接 - 通过任意大量的依赖代码,和...




  • 从标题中删除使用语句,或

  • < string> 或影响 std ::
  • ul>

    ...可能会破坏包含有问题的标头的代码。任一问题可能使依赖代码不可编译,并且甚至可能不会注意到问题,直到尝试另一编译。此外,由于使用语句而遭受的人可能不具有文件系统/代码仓库权限,公司权限等,以使用 c $ c>声明,也不修复其他受影响的客户端代码。



    也就是说,如果一个头在类或函数中只有using没有对超出范围的代码的影响,因此对std ::的更改的潜在影响大大降低。


    While reading from Bruce Eckel's "Thinking in C++" about namespaces, I encountered the following statement:

    However you'll virtually never see a using directive in a header file (at least not outside of scope). The reason is that using directive eliminate the protection of that particular namespace, and the effect last until the end of current compilation unit. If you put a using directive (outside of a scope) in a header file, it means that this loss of "namespace protection" will occur within any file that include this header, which often mean other header files.

    Would you please like to help me to comprehend the above statement with some easy example?

    解决方案

    Consider this program:

    line#
        1 #include <string>                                                               
        2                                                                                 
        3 using namespace std;                                                            
        4                                                                                 
        5 struct string { const char* p; };  // Beware: another string!
        6                                                                                 
        7 int main()                                                                      
        8 {                                                                               
        9     string x; // Error: ambiguous - which string is wanted?
       10 }
    

    If you try to compile it, you'll see errors:

    g++     using.cc   -o using
    using.cc: In function `int main()':
    using.cc:9: error: use of `string' is ambiguous
    using.cc:5: error:   first declared as `struct string' here
    /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stringfwd.h:60: error:
       also declared as `typedef struct std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::string' here
    using.cc:9: error: `string' was not declared in this scope
    using.cc:9: error: expected `;' before "x"
    

    The problem here is that when main() specifies string x;, the compiler's not sure whether the user-defined ::string or included std::string is wanted.

    Now imagine you take the top part of the program... lines 1 through 5 - up to and including the struct string... and put it into a header file which you then #include before main(). Nothing changes: you still have an error. So, just as for standalone programs, header files with using statements in them can cause trouble for other code that includes them, making some of their statements ambiguous.

    It can be a bigger pain though, as headers can be included - directly or indirectly - by arbitrarily huge amounts of dependent code, and...

    • removing the using statement from the header, or
    • a change to the contents of <string>, or any other header affecting std::

    ...might break code including the problematic header. Either problem may render dependent code uncompilable, and issues may not even be noticed until another compilation is attempted. Further, the person suffering due to the using statement may not have filesystem/code-repository permissions, corporate authority etc. to remove the using statement from the header, nor fix other affected client code.

    That said, if a header only has "using" inside a class or function, then there's no affect on code beyond that scope, so the potential impact of changes to std:: is dramatically reduced.

    这篇关于为什么包括“使用命名空间”到头文件中一个坏主意在C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆