100

考虑一对两个源文件:接口声明文件(*.h*.hpp)及其实现文件(*.cpp)。

*.h文件如下所示:

namespace MyNamespace {
  class MyClass {
  public:
    int foo();
  };
}

我已经看到了在源文件中使用命名空间的两种不同做法:

*.cpp展示练习#1:

#include "MyClass.h"
using namespace MyNamespace;

int MyClass::foo() { ... }

*.cpp展示练习#2:

#include "MyClass.h"
namespace MyNamespace {

  int MyClass::foo() { ... }

}

我的问题:这两种做法之间有什么区别吗?一种被认为比另一种更好吗?

4

6 回答 6

76

从代码可读性的角度来看,出于这个原因,我认为使用#2 方法可能更好:

您一次可以是using多个命名空间,并且写在该行下方的任何对象或函数都可以属于这些命名空间中的任何一个(除非命名冲突)。将整个文件包装在一个namespace块中更加明确,并且允许您在 .cpp 文件中声明属于该命名空间的新函数和变量

于 2012-05-30T12:52:08.287 回答
58

最清楚的是您没有显示的选项:

int MyNamespace::MyClass::foo()
{
    //  ...
}

它也很冗长;对大多数人来说太多了。由于using namespace这是名称冲突的一个原因,至少在我的经验中,并且应该避免,除非在非常有限的范围和地方,我通常使用你的#2。

于 2012-05-30T13:30:47.237 回答
11

这两种做法有什么区别吗

是的。#1 和 #2 分别是using 指令命名空间定义的示例。在这种情况下,它们实际上是相同的,但会产生其他后果。例如,如果您在 旁边引入一个新标识符MyClass::foo,它将具有不同的范围:

#1:

using namespace MyNamespace;
int x;  // defines ::x

#2:

namespace MyNamespace {
  int x;  // defines MyNamespace::x
}

一个被认为比另一个更好?

#1 优点:更简洁一些;更难在不经意间无意中引入某些东西MyNamespace。缺点:可能会无意中引入现有的标识符。

#2 优点:更清楚的是现有标识符的定义和新标识符的声明都属于MyNamespace. 缺点:更容易无意中将标识符引入MyNamespace.

对 #1 和 #2 的批评是,当您可能只关心MyNamespace::MyClass. 这是严厉的,它传达的意图很差。

#1 的一种可能替代方法是使用声明,其中仅包含您感兴趣的标识符:

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }
于 2016-06-01T20:57:40.070 回答
6

我还想补充一点,如果您由于某种原因决定在 cpp 文件中实现模板专业化并且仅仅依靠using namespace您将遇到以下问题:

// .h file
namespace someNameSpace
{
  template<typename T>
    class Demo
    {
      void foo();
    };
}

// .cpp file
using namespace someNameSpace;

template<typename T>
void Demo<T>::foo(){}

// this will produce
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive]
template<>
void Demo<int>::foo(){}

否则,如果您应用#2 方法,这会很好。

于 2016-06-04T12:26:59.173 回答
0

I'd like to add one more way, using using-declaration:

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

This way saves you from typing namespace name many time if class have many functions

于 2016-12-07T06:39:36.157 回答
0

我认为实践#1根本不是正确的 C++ 代码。此代码片段定义 ::MyClass::foo 符号,其中真正的全限定名称是 ::MyNamespace::MyClass::foo。

要了解命名空间,您可以阅读草案的第 7.3 节,比如说标准http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

这个概念从 1998 年左右开始就已经很老了,因此您可以使用 B.Stroustroup 的任何标准或书籍来了解它。

在 C++ 语言中,命名空间是一个命名范围。与类定义相反,命名空间可以向其添加新功能。

构造“使用命名空间 NS;” 在 C++ 中被称为 using-directive,在我的实践中它可以用于多个目标:

  1. 您可以在另一个命名空间中使用此指令来组合(混合)来自不同命名空间的名称。
  2. 在编译单元的上下文中,它会将同义词附加到命名空间NS中的所有变量。

要定义符号,您可以使用两种机制 - 您可以通过在 C++ 源文件中的全局命名空间中操作来对所有命名空间使用显式限定。

或者您可以打开命名空间并向其添加定义(练习 #2)。

于 2021-08-21T15:09:35.457 回答