我听说过使用名称空间std;这是不好的做法,我应该直接使用std::cout和std::cin。这是为什么?声明与std命名空间中的某个变量同名的变量是否有风险?


当前回答

命名空间是为了避免命名冲突。C++基于C,C在函数和变量名方面有很多问题,因为有时来自不同库的函数会发生冲突。因此,库开发人员开始在其函数前面加上库名,如下所示:

foo/foo.h:

void libfoo_foo_foo_h_open(); // the name can be weird then even this one!

C++引入了名称空间,以一种简单的方式解决了这个问题。

假设您有两个名为file和window的库,分别处理文件和窗口,代码如下:

#include <file.h>
#include <window.h>

using namespace file;
using namespace window;

void open() {
     ...
}

文件.h:

namespace file {
    void open(); // What!
}

window.h:

namespace window {
    void open(); // Oh no!
}

上面的代码肯定无法编译。

如果你不喜欢键入std::(只有5个字符),你可以一直这样做:(在头文件中不是个好主意)

using s = std;

如果您仍然想使用名称空间std;在您的源文件中,那么您正在引发这个问题,我必须问您“NAMESPACE的目的是什么?”。

其他回答

这都是关于管理复杂性的。使用名称空间会将您不想要的东西拉进来,因此可能会使调试变得更困难(我说可能)。到处使用std::很难阅读(更多的文本等等)。

马的课程-管理你的复杂性,尽你最大的能力和感觉。

不要全局使用它

只有在全球范围内使用时,它才被认为是“坏的”。因为:

你把正在编程的命名空间弄得乱七八糟。当您使用许多名称空间xyz;时,读者将很难看到特定标识符的来源;。无论对你的源代码的其他读者来说是什么,对最经常阅读源代码的读者来说更是如此:你自己。一两年后回来看看。。。如果您只讨论使用名称空间std;你可能不知道你抓取的所有内容——当你添加另一个#include或移动到一个新的C++修订版时,你可能会遇到你不知道的名称冲突。

您可以在本地使用

继续,在本地(几乎)自由使用它。当然,这可以防止你重复std::--,重复也是不好的。

本地使用它的习惯用法

在C++03中,有一种习惯用法——样板代码——用于为类实现交换函数。有人建议您实际使用本地using命名空间std;--或至少使用std::swap;:

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

这有以下魔力:

编译器将为value_选择std::swap,即void std::swap(int,int)。如果实现了重载void swap(Child&,Child&),编译器将选择它。如果没有重载,编译器将使用void std::swap(Child&,Child&),并尽可能地交换这些。

对于C++11,没有理由再使用这种模式了。对std::swap的实现进行了更改,以找到一个潜在的过载并选择它。

我不认为这在任何情况下都是不好的做法,但在使用它时都需要小心。如果你正在编写一个库,你可能应该在命名空间中使用作用域解析运算符,以防止你的库与其他库冲突。对于应用程序级代码,我看不出它有什么问题。

我也认为这是一种糟糕的做法。为什么?就在一天,我认为名称空间的功能是划分内容,所以我不应该将所有内容都放在一个全局包中而破坏它。

然而,如果我经常使用“cout”和“cin”,我会写:使用std::cout;使用std::cin;在.cpp文件中(当它使用include传播时,不会在头文件中)。我想,没有一个理智的人会说出一条小溪的名字

您需要能够阅读与您不同风格和最佳实践意见的人编写的代码。如果你只使用cout,没有人会感到困惑。但是,当你有很多名称空间到处飞的时候,你看到这个类,你不太确定它做什么时,让名称空间显式充当某种注释。您可以第一眼看到,“哦,这是一个文件系统操作”或“这是在做网络工作”。