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


当前回答

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

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


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

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

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

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

其他回答

命名空间是命名作用域。命名空间用于对相关声明进行分组并保持独立项目分开。例如,两个单独开发的库可以使用相同的名称来表示不同的项,但用户仍然可以同时使用这两个:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    // ...
}

namespace Yourlib{
    class Stack{ /* ... */ };
    // ...
}

void f(int max) {
    Mylib::Stack<int> s1(max); // Use my stack
    Yourlib::Stack    s2(max); // Use your stack
    // ...
}

重复名称空间名称可能会分散读者和作者的注意力。因此,有可能声明来自特定命名空间的名称在没有明确限定的情况下可用。例如:

void f(int max) {
    using namespace Mylib; // Make names from Mylib accessible
    Stack<int> s1(max); // Use my stack
    Yourlib::Stack s2(max); // Use your stack
    // ...
}

命名空间为管理不同库和不同版本的代码提供了强大的工具。特别是,它们为程序员提供了如何明确引用非本地名称的备选方案。

来源:C++编程语言概述作者:Bjarne Stroustrup

有经验的程序员使用任何解决他们问题的方法,避免任何产生新问题的方法。出于这个确切的原因,他们避免使用头文件级别的指令。

经验丰富的程序员也尽量避免在源文件中使用完全限定的名称。这样做的一个次要原因是,除非有充分的理由,否则在代码较少的情况下编写更多的代码是不优雅的。一个主要原因是关闭参数依赖查找(ADL)。

这些好理由是什么?有时程序员明确希望关闭ADL,有时他们希望消除歧义。

因此,以下内容是可以的:

函数级使用指令并在函数的实现中使用声明使用源文件内声明的源文件级别(有时)使用指令的源文件级别

下面是一个示例,展示了如何使用命名空间std;可能会导致名称冲突问题:

无法在C中定义全局变量++

在本例中,一个非常通用的算法名称(std::count)与一个非常合理的变量名称(count)冲突。

考虑

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // Uh oh
};

请注意,这是一个简单的示例。如果您有包含20个include和其他导入的文件,那么您将有大量的依赖项来解决问题。更糟糕的是,根据冲突的定义,在其他模块中可能会出现不相关的错误。

这并不可怕,但如果不在头文件或全局名称空间中使用它,您将省去麻烦。在非常有限的范围内执行它可能是正确的,但我从未遇到过键入额外的五个字符来澄清我的函数来自何处的问题。

为了回答你的问题,我实际上是这样看的:很多程序员(不是所有人)都调用命名空间std。因此,人们应该养成习惯,不要使用与命名空间std中的名称冲突或使用相同名称的东西。这是一个很大的事实,但与严格来说可能出现的连贯单词和假名的数量相比,这并不是那么多。

我是说真的。。。说“不要依赖于这个存在”只是让你依赖于它不存在。您经常会遇到借用代码片段并不断修复它们的问题。只需将用户定义的和借用的内容保持在有限的范围内,并且非常节省全局变量(老实说,全局变量几乎永远是“现在编译,以后理智”的最后手段)。我真的认为这是你老师的坏建议,因为使用std对“cout”和“std::cout”都有效,但不使用std只对“std:”cout有效。你不会总是幸运地编写自己的代码。

注意:在真正了解编译器的工作原理之前,不要过于关注效率问题。只要有一点编码经验,在你意识到他们能够将好的代码概括成简单的东西之前,你不必了解他们太多。每一点都很简单,就像你用C语言写了整件事一样。