为什么“使用名称空间标准”被认为是不好的做法?
其他人告诉我,在代码中using namespace std
编写是错误的,我应该直接使用std::cout
和std::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
命名空间有很多标识符,其中很多是非常常见的标识符(认为list
, sort
, string
, iterator
等),它们很可能出现在其他代码中。
如果你认为这是不太可能的:在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:";
上一篇: Why is "using namespace std" considered bad practice?
下一篇: How can I create an executable JAR with dependencies using Maven?