c++ - 为什么在 C++ 中将 "using namespace"包含到头文件中是个坏主意?

标签 c++ namespaces global-namespace

在阅读 Bruce Eckel 关于命名空间的“Thinking in C++”时,我遇到了以下陈述:

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.

您能否通过一些简单的例子帮助我理解上述陈述?

最佳答案

考虑这个程序:

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 }

如果你尝试编译它,你会看到错误:

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"

这里的问题是当main()指定 string x; ,编译器不确定是否用户定义的::string或包含std::string被通缉。

现在假设您使用程序的顶部...第 1 到第 5 行 - 直到并包括 struct string ...并将其放入一个头文件中,然后#include之前 main() .没有任何变化:您仍然有错误。因此,就像独立程序一样,带有 using 的头文件它们中的语句可能会给包含它们的其他代码带来麻烦,从而使它们的某些语句模棱两可。

这可能是一个更大的痛苦,因为标题可以直接或间接地包含在任意大量的依赖代码中,并且...

  • 删除 using标题中的声明,或
  • <string> 的内容进行了更改, 或任何其他影响 std:: 的 header

...可能会破坏代码,包括有问题的 header 。任何一个问题都可能导致相关代码无法编译,并且在尝试进行另一次编译之前甚至可能不会注意到问题。此外,因using而遭受痛苦的人声明可能没有文件系统/代码库权限、公司权限等来删除 using header 中的语句,也不修复其他受影响的客户端代码。

也就是说,如果 header 仅在类或函数中具有“使用”功能,那么超出该范围的代码不会受到影响,因此对 std::更改的潜在影响会大大降低。

关于c++ - 为什么在 C++ 中将 "using namespace"包含到头文件中是个坏主意?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4872373/

相关文章:

ruby - "pollute the global namespace"是什么意思?

C++:char test[100] vs array<char, 100> vs string

c++ - 如何动态构建和链接 boost::regex 与隐藏的内联?

c# - 命名空间中类的声明

javascript - 每次完整回发时,javascript 全局命名空间都会被清除吗?

c++ - istream 停止于\n

c++ - 在大型项目中按名称查找函数的最佳方法是什么?

c++ - 命名空间中的静态变量

c# - 两个VS2008 C#类库项目是否可以共享一个命名空间?