为什么“使用名称空间标准”被认为是不好的做法?

其他人告诉我,在代码中using namespace std编写是错误的,我应该直接使用std::coutstd::cin

为什么using namespace std被认为是一个不好的做法? 它效率低下还是会冒险声明不明确的变量(与std命名空间中的函数共享相同名称的变量)? 它会影响性能吗?


这根本与性能无关。 但考虑一下:你正在使用两个名为Foo和Bar的库:

using namespace foo;
using namespace bar;

一切正常,你可以从Foo和Quux()从Bar中调用Blah()而没有任何问题。 但有一天你升级到新版本的Foo 2.0,现在它提供了一个名为Quux()的函数。 现在你遇到了一个冲突:Foo 2.0和Bar将Quux()导入到你的全局命名空间中。 这将需要一些努力来解决,特别是如果函数参数匹配。

如果你使用过foo::Blah()bar::Quux() ,那么foo::Quux()的引入将是一个非事件。


我同意格雷格写的所有内容,但我想补充一点: 它甚至可能比格雷格说的更糟糕!

Library Foo 2.0可以引入一个函数Quux() ,这个函数与你的代码调用多年的bar::Quux()相比,对你对Quux()一些调用明确地更好地匹配。 然后你的代码仍然编译 ,但是它默默地调用了错误的函数 ,并且知道什么。 事情可能会变得很糟糕。

请记住std命名空间有很多标识符,其中很多是非常常见的标识符(认为listsortstringiterator等),它们很可能出现在其他代码中。

如果你认为这是不太可能的:在Stack Overflow上有一个问题,在我给出这个答案后的大约半年时间里发生了这个事情(由于省略了std::前缀而调用了错误的函数)。 这是另一个更近期的这样一个问题的例子。 所以这是一个真正的问题。


这里还有一个数据点:很多很多年前,我也习惯于发现它不得不使用std::标准库来std::前缀。 然后,我在一个开始决定using指令和声明被禁止的项目中工作,除了函数作用域。 你猜怎么了? 我们大多数人花了几个星期的时间才习惯于编写前缀,并且在几周之后,我们大多数人甚至都认为它确实使代码更具可读性。 这是有原因的: 无论你喜欢更短还是更长的散文是主观的,但前缀客观地增加了代码的清晰度。 不仅是编译器,而且你也会发现查看哪个标识符更容易。

十年后,该项目的规模增长到数百万行。 由于这些讨论上来一次又一次,我曾经很好奇多久(允许)函数范围using实际上是在项目中使用。 我为它找到了来源,只发现了一两个地方。 对我来说,这表明,一旦尝试过,开发人员即使在允许使用的情况下也不会发现std:: painful足够使用指令,即使每100 kLoC也使用一次。


底线:明确地加上前缀并不会造成任何伤害,只需要很少的习惯,并且具有客观的优势。 特别是,它使代码更容易被编译器和读者解读 - 而且这应该是编写代码时的主要目标。


我认为把它放在你的类的头文件中是不好的,因为那样你会迫使任何想使用你的类的人(通过包含你的头文件)也被'使用'(即看到所有内容)其他的名字空间。

但是,您可以随意在您的(私有)* .cpp文件中使用使用语句。


请注意,有些人不同意我这样的说法 - “像这样感觉自由” - 因为尽管cpp文件中的使用语句比标题中的使用语句要好(因为它不会影响包含头文件的人),但他们认为它仍然不好(因为根据代码,它可能会使课程的实施更难以维护)。 这个常见问题主题说,

using-directive存在于传统的C ++代码中,并且可以简化向命名空间的转换,但是您可能不应该定期使用它,至少不要在新的C ++代码中使用它。

它提出了两种选择:

  • 使用声明:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • 克服它,只需输入std ::

    std::cout << "Values:";
    
  • 链接地址: http://www.djcxy.com/p/775.html

    上一篇: Why is "using namespace std" considered bad practice?

    下一篇: How can I create an executable JAR with dependencies using Maven?