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


当前回答

在类的头文件中使用名称空间的问题在于,它迫使任何想要使用您的类(通过包括头文件)的人也“使用”(即查看其他名称空间中的所有内容)。

但是,您可以随意在(私有)*.cpp文件中放入using语句。


请注意,有些人不同意我这样说的“感觉自由”,因为尽管cpp文件中的using语句比头文件中的要好(因为它不会影响包含头文件的人),但他们认为这仍然不好(因为根据代码的不同,这可能会使类的实现更难维护)。这个C++超级FAQ条目说,

using指令存在于遗留的C++代码中,用于简化向命名空间的转换,但您可能不应该定期使用它,至少不应该在新的C++代码。

常见问题解答建议了两种选择:

使用声明:使用std::cout;//using声明允许您无条件使用coutcout<<“值:”;只需键入std::std::cout<<“值:”;

其他回答

是的,名称空间很重要。在我的项目中,我需要将一个var声明导入到源代码中,但在编译时,它与另一个第三方库冲突。

最后,我不得不用其他方法来解决这个问题,并使代码变得不那么清晰。

在类的头文件中使用名称空间的问题在于,它迫使任何想要使用您的类(通过包括头文件)的人也“使用”(即查看其他名称空间中的所有内容)。

但是,您可以随意在(私有)*.cpp文件中放入using语句。


请注意,有些人不同意我这样说的“感觉自由”,因为尽管cpp文件中的using语句比头文件中的要好(因为它不会影响包含头文件的人),但他们认为这仍然不好(因为根据代码的不同,这可能会使类的实现更难维护)。这个C++超级FAQ条目说,

using指令存在于遗留的C++代码中,用于简化向命名空间的转换,但您可能不应该定期使用它,至少不应该在新的C++代码。

常见问题解答建议了两种选择:

使用声明:使用std::cout;//using声明允许您无条件使用coutcout<<“值:”;只需键入std::std::cout<<“值:”;

为什么使用命名空间标准?

C++有一个标准库,其中包含构建应用程序时使用的常用功能,如容器、算法等。如果这些库使用的名称是公开的,例如,如果它们全局定义了一个队列类,那么您将无法再次使用相同的名称而不发生冲突。因此,他们创建了一个名称空间std来包含此更改。

不使用的原因1:不良行为

使用命名空间std的语句通常被认为是错误的做法。此语句的另一种方法是在每次声明类型时使用作用域运算符(::)指定标识符所属的命名空间。尽管该语句避免了我们在任何时候希望访问std命名空间中定义的类或类型时键入std::,但它将整个std命名空间导入到程序的当前命名空间中。

不使用的原因2:编译器变得混乱

在玩具程序中导入整个std库是可以的,但在生产级代码中,这是不好的。使用命名空间std;使命名空间std中声明的每个符号都可以在没有命名空间限定符的情况下访问。

例如:

现在,假设您升级到一个较新版本的C++,并将更多新的std命名空间符号注入到您不知道的程序中。您的程序中可能已经使用了这些符号。现在编译器将很难弄清楚声明的符号是属于您自己的实现,还是来自您在没有任何概念的情况下导入的名称空间。一些编译器会抛出错误。如果运气不好,编译器选择了错误的实现并编译它,这肯定会导致运行时崩溃。

命名空间污染影响:

虽然这种做法对于示例代码来说是可以的,但将整个std命名空间拉入全局命名空间是不好的,因为它会破坏命名空间的目的,并可能导致名称冲突。这种情况称为命名空间污染。

不应该在全局范围内使用using指令,尤其是在头中。但是,在某些情况下,即使是在头文件中,也会出现这种情况:

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; // No problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

这比显式限定(std::sin,std::cos…)更好,因为它更短,并且能够处理用户定义的浮点类型(通过依赖于参数的查找(ADL))。

这取决于它的位置。如果它是一个公共的头,那么通过将其合并到全局名称空间中,可以减小名称空间的值。请记住,这可能是制作模块全局的一种简单方法。