&引用;使用名称空间";在c++;标题 在我们所有的C++课程中,所有教师都使用名称空间STD来设置;代码>在#之后,将包含在其.h文件中。在我看来,这似乎是危险的,因为通过在另一个程序中包含该头,我将把名称空间导入到我的程序中,可能没有意识到、打算或想要它(头包含可以是非常深的嵌套)
所以我的问题是双重的:我是否正确地认为头文件中不应该使用&引用;使用名称空间";在c++;标题 在我们所有的C++课程中,所有教师都使用名称空间STD来设置;代码>在#之后,将包含在其.h文件中。在我看来,这似乎是危险的,因为通过在另一个程序中包含该头,我将把名称空间导入到我的程序中,可能没有意识到、打算或想要它(头包含可以是非常深的嵌套),c++,namespaces,header-files,C++,Namespaces,Header Files,所以我的问题是双重的:我是否正确地认为头文件中不应该使用使用名称空间,和/或是否有某种方法可以撤销它,比如: //header.h using namespace std { . . . } 同样,还有一个问题:头文件#应该包含它对应的.cpp文件需要的所有头文件,只包含头定义所需的头文件,并让.cpp文件包含其余的头文件,还是不包含,并将它需要的所有内容声明为extern? 这个问题背后的原因与上面相同:我不希望在包含.h文件时出现意外 还有,如果我是对的,这是一个常见的错误吗?我的意思是在
使用名称空间,和/或是否有某种方法可以撤销它,比如:
//header.h
using namespace std {
.
.
.
}
同样,还有一个问题:头文件#应该包含它对应的.cpp
文件需要的所有头文件,只包含头定义所需的头文件,并让.cpp
文件包含其余的头文件,还是不包含,并将它需要的所有内容声明为extern
?
这个问题背后的原因与上面相同:我不希望在包含.h
文件时出现意外
还有,如果我是对的,这是一个常见的错误吗?我的意思是在现实世界的编程和“真实”的项目中
谢谢。你说得对。任何文件都应该只包含该文件所需的标题。至于“做错事在现实世界的项目中是常见的吗?”-哦,是的 您是对的,在标题中使用命名空间是危险的。
我不知道如何撤销它。
检测它很容易,但是只需在头文件中使用名称空间搜索。
出于最后一个原因,这在实际项目中并不常见。如果有人这样做,更有经验的同事很快就会抱怨
在实际项目中,人们会尽量减少包含的文件数量,因为包含的文件越少,编译速度就越快。这节省了每个人的时间。但是,如果头文件假定在它之前应该包含某些内容,那么它应该包含它本身。否则,它会使标题不自包含。在标题中包含标题时需要小心。在大型项目中,它可以创建一个非常复杂的依赖链,触发比实际需要更大/更长的重建。检查并了解C++项目中良好物理结构的重要性。
只有在绝对需要时(无论何时需要类的完整定义),才应该在头中包含头,并尽可能使用前向声明(当需要类是指针或引用时)
至于名称空间,我倾向于在头文件中使用显式名称空间作用域,并且只在我的cpp文件中使用使用名称空间
。您绝对不应该在头文件中使用使用名称空间
,原因正是您所说的,它可能会意外地更改包含该头的任何其他文件中代码的含义。使用命名空间
无法撤消,这也是它如此危险的另一个原因。我通常只使用grep
或类似的方法来确保使用名称空间
不会在标题中被调用,而不会尝试任何更复杂的操作。可能静态代码检查器也会标记这一点
头应该只包括需要编译的头。执行此操作的一个简单方法是,在任何其他头之前,始终首先包含每个源文件自己的头。如果头文件不是自包含的,那么源文件将无法编译。在某些情况下,例如引用库中的实现细节类,您可以使用前向声明而不是#include
,因为您可以完全控制此类前向声明类的定义
我不确定我会称之为“普通”,但它肯定会偶尔出现,通常是由没有意识到负面后果的新程序员编写的。通常,只要对风险进行一点教育,就可以解决任何问题,因为修复起来相对简单。与编程中的所有事情一样,我认为实用主义应该战胜教条主义
只要您在整个项目范围内做出决策(“我们的项目广泛使用STL,我们不想用std::。”预先准备所有内容”),我就看不出它有什么问题。毕竟,你唯一要冒的风险就是名称冲突,而且随着STL的普及,这不太可能成为一个问题
另一方面,如果这是一个开发人员在单个(非私有)头文件中做出的决定,我可以看出这会在团队中产生混乱,应该避免。Sutter和Alexandrescu的第59项:
59。不要在头文件中或在包含之前写入命名空间。
命名空间使用
s是为了您的方便,而不是为了您对他人施加影响:切勿在#include
指令之前编写使用
声明或使用
指令
推论:在头文件中,不要使用
指令或使用
声明编写命名空间级别的;而是显式地限定所有名称
头文件是一个或多个源文件中的来宾文件。一个包含指令和声明的头文件也会带来它的好朋友
使用
声明的会带来一个好友。使用
指令的会引入名称空间中的所有伙伴。你的老师使用名称空间std
是一个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;
#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