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

可能是复制品,但不容易找到。

如果有这样的标题:

namespace ns1
{
class MyClass
{
void method();
};
}

I've see method() defined in several ways in the .cpp file:

版本一:

namespace ns1
{
void MyClass::method()
{
...
}
}

第二版:

using namespace ns1;


void MyClass::method()
{
...
}

第三版:

void ns1::MyClass::method()
{
...
}

有没有“正确”的方法来做这件事?这些“错误”中有没有一个意思是不一样的呢?

62378 次浏览

Version 2 is unclear and not easy to understand because you don't know which namespace MyClass belongs to and it's just illogical (class function not in the same namespace?)

版本1是正确的,因为它显示了在名称空间中,您正在定义函数。

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

参见 名称空间(C + +)。这是做到这一点的最佳方法。

版本3使得类和名称空间之间的关联非常明确,但是代价是更多的类型。版本1避免了这一点,但是捕获了与块的关联。版本2倾向于隐藏这一点,所以我会避免那一个。

All the ways are right, and each one has its advantages and disadvantages.

In the version 1, you have the advantage of not having to write the namespace in front of each function. The disadvantage is that you'll get a boring identation, specially if you have more than one level of namespaces.

在版本2中,您可以使代码更加清晰,但是如果您在 CPP 中实现了多个名称空间,那么其中一个可以直接访问另一个的函数和变量,从而使您的名称空间无用(对于 CPP 文件)。

在版本3中,你需要输入更多的内容,而且你的函数行可能比屏幕大,这对设计效果不利。

还有一些人使用它的另一种方式。它类似于第一个版本,但没有标识问题。

是这样的:

#define OPEN_NS1 namespace ns1 {
#define CLOSE_NS1 }


OPEN_NS1


void MyClass::method()
{
...
}


CLOSE_NS1

对于每种情况,选择哪一个更好取决于你

我选择 Num.3(也称为详细版本)。它更多的是输入,但其意图对于您和编译器都是精确的。你发布的问题实际上比现实世界要简单。在现实世界中,定义还有其他作用域,而不仅仅是类成员。您的定义对于类来说并不复杂——因为它们的作用域永远不会重新打开(不像名称空间、全局作用域等)。

这可能会因为类以外的其他作用域而失败——任何可以重新打开的东西。因此,您可以使用这种方法在名称空间中声明一个新函数,或者您的内联可能会通过 ODR 被替换。对于某些定义(特别是模板专门化) ,您将需要它。

这是非常脆弱的,特别是在大型代码库中——当头和依赖项发生变化时,您的程序将无法编译。

编号3这是一个理想的选择,但是需要输入很多内容——定义 什么的的目的是什么。这正是这样做,编译器启动以确保您没有犯错误,定义没有与其声明不同步,等等。.

我使用版本4(下面)是因为它结合了版本1(反向定义的简洁性)和版本3(最大限度地显式)的大部分优点。主要的缺点是,人们不习惯它,但因为我认为它在技术上优于其他选择,我不介意。

版本4: 使用名称空间别名进行完全限定:

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

在我的世界里,我经常使用名称空间别名,因为所有东西都是显式限定的——除非它不能(例如变量名)或者它是一个已知的定制点(例如函数模板中的交换())。

事实证明,这不仅仅是“编码风格的问题”。Num.2导致在头文件中定义和初始化声明的外部变量时出现链接错误。看看我问题中的例子。Cpp 文件中命名空间中常量的定义

5年后,我想我应该提一下这个,看起来不错,也不邪恶

using ns1::MyClass;


void MyClass::method()
{
// ...
}

Googles C++ Style Guide dictates your version 1, without indentation though.

Googles C++ Style Guide for namespaces