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

可能是重复的,但不是一个容易的search…

给定一个头像:

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

我看到.cpp文件中以几种方式定义了method()

版本1:

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

版本2:

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

版本3:

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

有没有一个“正确”的方法来做到这一点? 这些“错误”中的任何一个都不意味着同一件事情?

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

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

版本3也是正确的,因为您使用:: scopeparsing运算符来引用名称空间ns1MyClass::method () 。 我更喜欢版本3。

请参阅命名空间(C ++) 。 这是做到这一点的最好方法。

我使用版本4(下面),因为它结合了版本1(简洁的定义)和版本3(最大限度的明确)的大部分优点。 主要缺点是人们不习惯,但是由于我认为它在技术上优于我不介意的select。

版本4:使用命名空间别名的完整限定:

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

在我的世界里,我经常使用名称空间别名,因为所有的东西都被明确地限定了 – 除非它不能(例如variables名)或者它是已知的定制点(例如函数模板中的swap())。

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

 using ns1::MyClass; void MyClass::method() { // ... } 

版本3使得类和名称空间之间的关联变得非常明确,而牺牲了更多的input。 版本1避免了这一点,但捕获了与块的关联。 版本2往往隐藏这个,所以我会避免这一个。

事实certificate,这不仅是“编码风格的问题”。 民。 2在定义和初始化头文件中声明为extern的variables时导致链接错误。 看看我的问题中的例子。 cpp文件中命名空间内常量的定义

所有的方法都是正确的,每一个都有其优点和缺点。

在版本1中,您可以不必在每个函数前写入名称空间。 缺点是你会得到一个无聊的标识,特别是如果你有多个级别的命名空间。

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

在版本3中,您必须input更多的内容,并且您的function行可能比屏幕更大,这对devise效果不利。

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

就像这样:

 #define OPEN_NS1 namespace ns1 { #define CLOSE_NS1 } OPEN_NS1 void MyClass::method() { ... } CLOSE_NS1 

这取决于你select哪个更适合每种情况=]

我selectNum.3(又名详细版本)。 这是更多的打字,但意图是准确的,你和编译器。 你发布的问题实际上比现实世界简单。 在现实世界中,还有其他的定义范围,而不仅仅是类的成员。 你的定义并不是很复杂的类,因为它们的范围不会重新打开(不像命名空间,全局范围等)。

Num.1这可能会失败,而不是类的范围 – 任何可以重新打开的东西。 所以,你可以使用这种方法在名字空间中声明一个新的函数,或者你的内联可以通过ODR代替。 您将需要一些定义(特别是模板专门化)。

Num.2这是非常脆弱的,特别是在大型的代码库中 – 随着头文件和依赖关系的改变,你的程序将无法编译。

数字3这是理想的,但很多types – 你的意图是什么定义的东西 。 这确实如此,并且编译器会确保您没有犯错误,定义与其声明不同步。

谷歌C + +风格指南规定您的版本1,但没有缩进。

谷歌C ++风格指南命名空间