3

可能重复:
使用 std 命名空间
为什么是“使用命名空间 std;” 在 C++ 中被认为是一种不好的做法?

假设我#include <iostream>在 C++ 中使用并且我正在制作一个打印语句。我可以选择:

using namespace std;
[...]
cout << "Hello" << endl;

或者

using std::cout;
using std::endl;
[...]
cout << "Hello" << endl;

或者

std::cout << "Hello" << std::endl;

我被引导相信,也许这是不正确的,第一个应该避免,因为它会给你的程序增加很多不必要的膨胀。不过,不知道第二款和第三款在性能上是否有区别。我看到的大多数使用库的代码都倾向于使用第三种风格。但是对我来说,如果在使用第二种方法时没有权衡,它似乎是最干净、最易读的方法,尤其是当您对相关函数或对象进行大量调用时。

任何人都可以启发我吗?

4

4 回答 4

11

无论您选择哪种方式,都没有性能差异或“膨胀”。

但是,如果你这样做,例如

using namespace std;
using namespace boost;

两个命名空间中的名称冲突会给您带来很多麻烦。

我认为std::cout在任何地方都使用 etc 的版本 3 更易于阅读,并且可以避免将来出现名称冲突。

如果这不是您想要的,选项 2 是第二好的,因为它只从命名空间中引入了一些选择名称。请注意,尽管在您的示例中,键入会造成净损失,因为 using 声明包含字符比不键入std::其余代码所节省的字符多。

于 2012-08-07T11:58:35.247 回答
8

我的经验法则:永远不要放入using namespace.h,但可以随意在.cpp文件中使用它。尤其是当它using namespace std

于 2012-08-07T11:56:56.820 回答
4

这些中的每一个生成的代码应该完全相同。从一开始就不会有任何膨胀,因为它只是std在编译时使所有名称都可用于代码 - 未使用的内容不会被采用。std实际使用的唯一名称是coutendl因此编译代码的最终结果是相同的。

优点和缺点是:

  1. 这将在大多数行中包含更简洁的代码。阅读它的人可能不得不更努力地考虑在哪里定义coutendl定义,尽管对于像他们这样知名的东西来说,这并不是一个大问题。编译可能需要更长的时间,因为每个名称的可能含义范围稍大一些,但这可能可以忽略不计,除非程序很大并且您正在编译的机器非常弱。如果范围内的某个其他名称空间定义了 ancout或 an,endl那么名称将不明确,您将被迫使用其他名称空间之一。

  2. 1号的优点,只带两个名字就减少了缺点。

  3. 与第一名相反。编译器和开发人员在查看源代码时都没有歧义,但代价是更加冗长。

std因此,如果这些是整个文件中的唯一用途,则可能值得采用方法 3 ,如果std重复使用的东西很多,则使用方法 3,如果您使用cout很多endl,则使用方法 2,但std.

或者您可以一直使用数字 1,除非由于歧义而被迫这样做。

两者并不相互排斥。一个可以做到:

using namespace std;
/*...*/
std::cout << "Hello" << std::endl;

这里当然是多余的,但是如果这些在上下文中是模棱两可的,但其他用途不是,或者如果人们可能不熟悉特定名称,那么冗余代码有助于可读性std::,我们可能会这样做。std还有一些以这种方式给出全名的更常见的名称,并且做常见的事情本身就有助于提高可读性。

尽管如此,除非出现歧义(不会编译),否则所有这些都会在编译时产生相同的程序。

编辑:

我在这里假设一个 .cpp 文件,但我同意其他人关于标题的看法。在 .h 文件中,您强制对包含在其中的所有文件做出决定,并且只需要一个模棱两可就可以做出错误的决定。开发人员也不太容易看到它,因为包含的地方并不靠近使用地点。

如果您真的想在 .h 文件中使用 1 或 2 ,则using通过将其放置在命名空间、类或函数中来确定其范围,这样包含该文件的人就不会有任何意外。

于 2012-08-07T12:09:03.790 回答
3

我通常更喜欢第三种样式,但有时使用第一种或第二种样式更加紧凑和简单。我有时在本地使用它们。例如:

void foo()
{
    using namespace std;
    //do stuff
}

但我不喜欢using namespace std在模块中全局编写

于 2012-08-07T11:54:14.833 回答