考虑一对两个源文件:接口声明文件(
*.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() { ... }
}
我的问题:这两种做法之间有什么区别吗?一种被认为比另一种更好?
从代码可读性的角度来看,我认为使用#2 方法可能更好,因为这个原因:
您可以同时成为多个命名空间,并且该行下方编写的任何对象或函数都可以属于任何这些命名空间(除非命名冲突)。将整个文件包装在
using
块中更加明确,并且允许您在 .cpp 文件中声明属于该命名空间的新函数和变量namespace
它也非常冗长;对于大多数人来说太多了。由于
int MyNamespace::MyClass::foo()
{
// ...
}
是名称冲突的根源,至少根据我的经验, 除非在非常有限的范围和地方,否则应该避免,我 一般使用你的#2。
using-directive是的。 #1 和 #2 分别是
和namespace定义的示例。在这种情况下,它们实际上是相同的,但会产生其他后果。例如,如果您在 using namespace
旁边引入一个新标识符,它将具有不同的范围:
#1:
MyClass::foo
#2:
using namespace MyNamespace;
int x; // defines ::x
一个被认为比另一个更好吗?
#1 优点:更简洁一点;更难无意中无意间将某些东西引入
namespace MyNamespace {
int x; // defines MyNamespace::x
}
。缺点:可能会无意中引入现有标识符。
#2 优点:更清楚的是,现有标识符的定义和新标识符的声明都属于
MyNamespace
。缺点:更容易无意中引入标识符
MyNamespace
。对 #1 和 #2 的批评是,当您可能只关心
MyNamespace
成员的定义时,它们指的是整个命名空间。这是一种严厉的做法,并且很难传达意图。
#1 的可能替代方案是 using-declaration
#include "MyClass.h"
using MyNamespace::MyClass;
int MyClass::foo() { ... }
,您将遇到以下问题:
using namespace
否则如果你应用#2方法就可以了。
:
// .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(){}
如果一个类有很多函数,这可以避免您多次键入名称空间名称。
根本不是正确的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++ 语言中,
namespace是命名范围。与类定义相反,命名空间可以向其中添加新函数。 C++ 中的构造
“using namespace NS;”称为 using 指令,在我的实践中它可以用于多个目标:
您可以在另一个命名空间中使用此指令来组合(混合)来自不同命名空间的名称。或者您可以打开名称空间并向其添加定义(练习#2)。