因此,我已经看到命名空间对于将声明组织到各自的组中是多么有用,但现在出现了一个问题。
在 C 中创建库和在 C++ 中创建库之间的区别在于,在 C 中,您必须在声明前加上它们所属的内容,例如,我们将称为 MyMath 的库可能有一个向量类,名称可能是 MM_Vector。
在 C++ 中,您将有一个名称空间 MyMath,其中声明了一个 Vector 类作为其一部分。
现在这里的区别是在 C 中,只需转到类声明,您就立即知道如何使用它。在 C++ 中,您必须检查特定类属于哪个命名空间(实际上,只有声明不在命名空间声明附近的文件中才会出现问题,如果两者之间声明了常量和枚举,则这种情况很常见)。虽然我更喜欢使用名称空间进行组织,但在我看来,这仍然是一个有效的论据,但令人烦恼。
人们做了什么来减少这种烦恼?
So, I've seen how useful namespaces can be to organize declarations into their respective groups, but now comes an issue with this.
The difference between making a library in C and a library in C++ is in C you must prefix your declarations with what they belong to, for example a library we'll dub MyMath might have a vector class, well the name might be MM_Vector.
In C++, you would have a namespace MyMath with a Vector class declared as a part of it.
Now the difference here is in C, just by going to the class declaration you immediately know how to use it. In C++, you would have to check which namespace a particular class belongs to (really only a problem in files where the declaration isn't near the namespace declaration, which can be common if there are constants and enumerations declared between the two). While I prefer using a namespace for organization, in my opinion this is still a valid argument as an annoyance.
What have people done to reduce this annoyance?
发布评论
评论(5)
在他的书的第8章中,Stroustrup推荐了如下的样式:
MyMath.h
Vector.h
Vector.cc
将开放命名空间声明限制为其内容声明会生成简短的摘要。完全限定的定义允许编译器捕获拼写错误。
正如您所关心的,这种风格的类声明和定义使每个类的父命名空间变得简单 - 代价是 Go 人员所说的 口吃。
In chapter 8 of his book, Stroustrup recommends a style such as the following:
MyMath.h
Vector.h
Vector.cc
Limiting open namespace-declarations to declarations of their contents produces brief summaries. Fully-qualified definitions allow the compiler to catch typos.
As applied to your concern, class declarations and definitions in this style make plain the parent namespace of each class—at the expense of what the Go folks call stuttering.
使用提供快速提示和符号导航的 IDE 和/或使用文档生成器(例如 Doxygen)。
Use an IDE that provides quick tips and symbol navigation and/or use document generators (e.g. Doxygen).
“只有声明不在命名空间声明附近的文件中才会出现问题,如果两者之间声明了常量和枚举,则这可能很常见)。”
如果这让您烦恼,请执行以下操作:
与类不同,您不必一起定义名称空间。括号并不意味着“这就是所有的东西”,它们只是表示一个范围,其中所有定义都位于该名称空间中,并且所有符号都在该名称空间中查找。
"only a problem in files where the declaration isn't near the namespace declaration, which can be common if there are constants and enumerations declared between the two)."
If that bothers you, do this:
Unlike a class, you don't have to define a namespace all together. The brackets don't mean "this is everything there is", they just denote a scope in which all definitions are into that namespace, and all symbols are looked up in the namespace.
应该没有问题。只需确保任何标头中都没有
using
语句,并且没有单一的源文件。如果这是一个大问题,请完全限定您的课程。There shouldn't be a problem. Just make sure there are never
using
statements in any header, and don't have monolithic source files. If it's a big problem, fully qualify your classes.您描述的问题归结为您所处的心态。在开发代码时,您非常清楚您正在使用
MyMath::Vector
,因此您有兴趣看到尽可能少的内容尽可能混乱,并添加using namespace MyMath;
或using MyMath::Vector;
子句。几个月后,有人进入您的代码,并且不知道
Vector
来自哪个命名空间。他可能会争辩说(就像您所做的那样)这个using
声明使代码更难以理解。这就是优秀 IDE 的用武之地:您可以将命名空间(对于大型系统来说,实际上可能会变得相当大)保留下来,但是在调试/编辑代码时,IDE 可以完美地提示您声明、定义符号的位置、引用等...
The problem you describe boils down to the mindset you're in. When developing the code, you know darn well that you're using the
MyMath::Vector
, so you're interested in seeing as little clutter as possible, and add ausing namespace MyMath;
orusing MyMath::Vector;
clause.Just after a couple of months, someone drops into your code, and doesn't know what namespace the
Vector
is coming from. He might argue (as you did) that thisusing
declaration makes the code less comprehensible.And that is where the good IDE comes in: you can leave namespace (which can become quite large, really, for big systems) out, but when debugging/editing the code, the IDE can perfectly hint you where the symbol was declared, defined, referenced etc...