C++:命名空间——如何在头文件和源文件中正确使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10816600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:29:50  来源:igfitidea点击:

C++: Namespaces -- How to use in header and source files correctly?

c++namespacesheader-files

提问by nickolay

Consider a pair of two source files: an interface declaration file (*.hor *.hpp) and its implementation file (*.cpp).

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

Let the *.hfile be like the following:

*.h文件如下所示:

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

I have seen two different practices for using namespaces in source files:

我见过在源文件中使用命名空间的两种不同做法:

*.cppshowing practice #1:

*.cpp展示练习#1:

#include "MyClass.h"
using namespace MyNamespace;

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

*.cppshowing practice #2:

*.cpp展示练习#2:

#include "MyClass.h"
namespace MyNamespace {

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

}

My question:Are there any differences between these two practices and is one considered better than the other?

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

采纳答案by Dan F

From a code readability standpoint, it is probably better in my opinion to use the #2 method for this reason:

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

You can be usingmultiple namespaces at a time, and any object or function written below that line can belong to any of those namespaces (barring naming conflicts). Wrapping the whole file in a namespaceblock is more explicit, and allows you to declare new functions and variables that belong to that namespace within the .cpp file as well

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

回答by James Kanze

The clearest is the option you didn't show:

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

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

It's also very verbose; too much so for most people. Since using namespaceis a recepe for name conflicts, at least in my experience, and should be avoided except in very limited scopes and places, I generally use your #2.

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

回答by John McFarlane

Are there any differences between these two practices

这两种做法有什么区别吗

Yes. #1 and #2 are examples of a using-directiveand a namespace definitionrespectively. They are effectively the same in this case but have other consequences. For instance, if you introduce a new identifier alongside MyClass::foo, it will have a different scope:

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

#1:

#1:

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

#2:

#2:

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

is one considered better than the other?

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

#1 Pros: a little more terse; harder to accidentally introduce something into MyNamespaceunwittingly. Cons: may pull in existing identifiers unintentionally.

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

#2 Pros: more clear that definitions of existing identifiers and declarations of new identifiers both belong to MyNamespace. Cons: easier to unintentionally introduce identifiers to MyNamespace.

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

A criticism of both #1 and #2 is that they are referring to an entire namespace when you probably only care about the definition of members of MyNamespace::MyClass. This is heavy-handed and it communicates the intent poorly.

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

A possible alternative to #1 is a using-declarationwhich includes only the identifier you're interested in:

#1 的一个可能替代方案是using 声明,它仅包含您感兴趣的标识符:

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

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

回答by Jordan

I'd like also to add that if you decide due to some reason to implement a template specialization in a cpp file and just rely on using namespaceyou will run into the following problem:

我还想补充一点,如果您出于某种原因决定在 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(){}

Otherwise if you apply #2 method this will be fine.

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

回答by Joanna

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

我想添加另一种方式,使用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

如果类有很多功能,这种方式可以避免多次输入命名空间名称