为什么包括“使用命名空间"?在 C++ 中放入头文件是个坏主意?
在阅读 Bruce Eckel 关于命名空间的Thinking in C++"时,我遇到了以下陈述:
While reading from Bruce Eckel's "Thinking in C++" about namespaces, I encountered the following statement:
但是,您几乎永远不会看到在头文件中使用指令(至少不在范围之外).这原因是 using 指令消除对它的保护特定的命名空间,以及效果持续到当前结束编译单元.如果你把一个使用指令(范围之外)头文件,就意味着这个丢失命名空间保护"将发生在任何包含此文件的文件标头,通常表示其他标头文件.
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?
推荐答案
考虑这个程序:
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"
这里的问题是当main()
指定string x;
时,编译器并不确定用户定义的::string
或包含 std::string
是想要的.
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.
现在假设您将程序的顶部...从第 1 行到第 5 行 - 直到并包括 struct string
... 并将其放入头文件中,然后您 #include
在 main()
之前.没有任何变化:您仍然有错误.因此,就像对于独立程序一样,带有 using
语句的头文件可能会给包含它们的其他代码带来麻烦,从而使它们的某些语句模棱两可.
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...
- 从标题中删除
using
语句,或 - 对
<string>
内容的更改,或任何其他影响std::
的标头
- removing the
using
statement from the header, or - a change to the contents of
<string>
, or any other header affectingstd::
...可能会破坏代码,包括有问题的标头.任何一个问题都可能导致相关代码无法编译,并且在尝试进行另一次编译之前甚至可能不会注意到问题.此外,因 using
语句而受苦的人可能没有文件系统/代码存储库权限、公司权限等来从标头中删除 using
语句,也没有修复其他受影响的客户端代码.
...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.
也就是说,如果标头仅在类或函数中具有使用"功能,那么超出该范围的代码不会受到影响,因此对 std:: 更改的潜在影响会大大降低.
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.
相关文章