Bar*_*uch 115 c++ namespaces header-files
在我们所有的C++课程,所有的老师总是把using namespace std;在之后#include在它们的S .h文件.从那时起,我觉得这很危险,因为在另一个程序中包含该标题我会将命名空间导入到我的程序中,可能没有意识到,打算或想要它(标题包含可以非常深入嵌套).
所以我的问题是双重的:我是对的,using namespace不应该在头文件中使用,和/或是否有某种方法来撤消它,例如:
//header.h
using namespace std {
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
还有一个问题是:标题文件是否应该是#include相应.cpp文件所需的所有标题,只有那些标题定义所需的标题,并让.cpp文件#include为其余标题,或者没有,并声明它需要的所有内容extern?
问题背后的原因与上面相同:在包含.h文件时我不想要惊喜.
另外,如果我是对的,这是一个常见的错误吗?我的意思是在现实世界的编程和"真正的"项目中.
谢谢.
Mar*_*k B 111
你绝对不应该using namespace在标题中使用它,因为它可以意外地改变包含该标题的任何其他文件中代码的含义.没有办法撤消using namespace这是另一个如此危险的原因.我通常只是使用grep或类似的东西,以确保using namespace没有在标题中调出,而不是尝试任何更复杂的东西.可能静态代码检查器也会标记这一点.
标题应该只包含它需要编译的标题.一种简单的方法是在任何其他标头之前始终将每个源文件自己的标头包含在内.如果标头不是自包含的,则源文件将无法编译.在某些情况下,例如,引用库中的实现详细信息类,您可以使用前向声明,而不是#include因为您可以完全控制此类前向声明的类的定义.
我不确定我会把它称为常见,但它肯定会偶尔出现,通常是由不了解负面后果的新程序员编写的.通常只需要对风险进行一点教育即可解决任何问题,因为修复起来相对简单.
And*_*mas 25
Sutter和Alexandrescu的"C++编码标准:101规则,指南和最佳实践"中的第59项:
- 不要在头文件中或#include之前编写命名空间.108
所有指南的标题都在http://www.gotw.ca/publications/c++cs.htm,但细节是C++开发人员必读的内容.
关于“有没有办法撤销[using声明]?”
我认为指出using声明受范围影响是有用的。
#include <vector>
{ // begin a new scope with {
using namespace std;
vector myVector; // std::vector is used
} // end the scope with }
vector myOtherVector; // error vector undefined
std::vector mySTDVector // no error std::vector is fully qualified
Run Code Online (Sandbox Code Playgroud)
如此有效,是的。通过限制using声明的范围,其效力仅在该范围内持续;当该范围结束时,它被“撤销”。
当using声明在任何其他范围之外的文件中声明时,它具有文件范围并影响该文件中的所有内容。
在头文件的情况下,如果using声明在文件范围内,这将扩展到包含头文件的任何文件的范围。
查看戈达德太空飞行中心编码标准(C和C++).结果比过去有点困难 - 请参阅SO问题的更新答案:
GSFC C++编码标准说:
§3.3.7每个头文件都应该
#include是编译#include所需的文件,而不是强迫用户使用所需的文件.#includes应限于标题所需的内容; 其他#includes应该放在源文件中.
第一个交叉引用的问题现在包括GSFC C编码标准的引用和基本原理,但实质内容最终是相同的.
你是对的,using namespace在标题是危险的.我不知道如何撤消它.它很容易检测到,但只搜索using namespace头文件.出于这个最后的原因,它在实际项目中并不常见.如果有人做类似的事情,更有经验的同事很快就会抱怨.
在实际项目中,人们会尝试最小化包含文件的数量,因为包含的文件越少,编译的速度就越快.这节省了每个人的时间.但是,如果头文件假定应该在它之前包含某些内容,那么它应该包含它本身.否则它会使标题不是自包含的.
我相信,如果您在嵌套命名空间中编写声明,则可以安全地在 C++ 标头中使用“using”:
namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED
{
/*using statements*/
namespace DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED
{
/*declarations*/
}
}
using namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED::DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED;
Run Code Online (Sandbox Code Playgroud)
这应该只包括“DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED”中声明的内容,而不包含使用的命名空间。我已经在 mingw64 编译器上测试过了。
| 归档时间: |
|
| 查看次数: |
71608 次 |
| 最近记录: |