在.cpp文件中定义C++命名空间方法的正确方法

Mr.*_*Boy 100 c++ coding-style namespaces

可能是重复的,但不是一个容易搜索的...

给出如下标题:

namespace ns1
{
 class MyClass
 {
  void method();
 };
}
Run Code Online (Sandbox Code Playgroud)

我看到method()在.cpp文件中以多种方式定义:

版本1:

namespace ns1
{
 void MyClass::method()
 {
  ...
 }
}
Run Code Online (Sandbox Code Playgroud)

版本2:

using namespace ns1;

void MyClass::method()
{
 ...
}
Run Code Online (Sandbox Code Playgroud)

版本3:

void ns1::MyClass::method()
{
 ...
}
Run Code Online (Sandbox Code Playgroud)

有没有'正确'的方法呢?这些都是"错误的",因为它们并不都意味着同样的事情吗?

GIL*_*ESH 46

版本2不清楚,不易理解,因为你不知道哪个命名空间MyClass属于哪个而且它只是不合逻辑的(类函数不在同一个命名空间中?)

版本1是正确的,因为它表明在命名空间中,您正在定义函数.

版本3也是正确的,因为您使用::范围解析运算符来引用MyClass::method ()命名空间中的ns1.我更喜欢第3版.

请参阅命名空间(C++).这是执行此操作的最佳方式.

  • 称#2"错误"是一种夸张的夸张.通过这种逻辑,所有符号名称都是"错误的",因为它们可能隐藏其他范围中的其他符号名称. (19认同)
  • 我同意@PhoenicaMacia,*使用*技巧很糟糕,可能导致混乱.考虑一个实现运算符作为自由函数的类,在头文件中你可以使用`namespace N {struct X {void f(); }; X运算符==(X const&,X const&); 现在在带有*using*语句的cpp文件中,您可以将成员函数定义为`void X :: f(){}`,但是如果定义`X operator ==(X const&,X const&)`您将定义与标题中定义的运算符不同的运算符(您必须使用1或3作为自由函数). (3认同)

Puz*_*tia 25

5年后,我想我会提到这一点,这看起来很好,也不是邪恶的

using ns1::MyClass;

void MyClass::method()
{
  // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案。它看起来最干净,并且避免了 OP 版本 1 的问题,它可能会无意中将事物带入命名空间,而 2 可能会无意中将事物带入全局空间。 (3认同)

Die*_*ühl 13

我正在使用版本4(下面),因为它结合了版本1(resoective定义的简洁性)和版本3(最大限度地显示)的大部分优点.主要缺点是人们不习惯它,但因为我认为它在技术上优于我不介意的替代品.

版本4:使用命名空间别名使用完全限定条件:

#include "my-header.hpp"
namespace OI = outer::inner;
void OI::Obj::method() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

在我的世界中,我经常使用命名空间别名,因为一切都是显式限定的 - 除非它不能(例如变量名)或它是一个已知的定制点(例如函数模板中的swap()).


Bja*_*sen 6

Googles C++ Style Guide规定了您的版本 1,但没有缩进。

命名空间的 Google C++ 风格指南