我被Java,C#和AS3感染了,我一直想以同样的方式使用C++命名空间,但我一直在读,他们并没有真正考虑到这一点.
有没有正确的方法来使用命名空间?例如,在由十几个库项目组成的代码库中(比如图形,声音,数学等等)和几个应用程序项目,该怎么办?是对还是错/开发者偏好:
MyCompanyName或MyProjectName命名空间中?是否有官方规则/指南作为C++的一部分,或者只有人们倾向于遵循的建议?
jal*_*alf 15
正如我在评论@Nim的答案中提到的那样,关键是要提出一个实用的结构.
例如,如果你看一下.NET框架,它的命名空间就有很长的名字并且是深层嵌套的(Say,System.Collections.Generic.List<T>).这同样适用于Java.对于嵌套的命名空间,你有很长的名字,没有任何效果.
我第一次创建一个List类时,我将遇到名称冲突,这是命名空间应该阻止的.(因为这似乎给了一个评论者一个错误的想法,当然我能够创建自己的List类.但是每次我使用它时,我都有可能遇到冲突."标准" List或它的命名空间都非常常用的,所以我很有可能using在命名空间上有一个,这意味着,如果我也想在同一个文件中引用我自己的 List类,我会发生冲突)
相比之下,C++标准库几乎将所有内容放在一个简单的std命名空间中(以及一些内容std::ios)
实际上,.NET命名空间实际上是浪费精力.它们没有效果.每个代码文件都以一长串列表开头using X; using Y; using Z,因此实际效果是在编写代码时没有任何名称空间实际生效.为了创建一个int列表,我就这样做了List<int>.命名空间基本消失了.
在C++中,人们不鼓励使用using namespace std,因此为了使用标准库符号,我们使用std前缀:std::vector<int>.
Boost使用类似的东西:几乎所有东西都在 boost根命名空间中.然后将一些复杂的库放在子命名空间中,例如boost::filesystem.或者boost::mpl,某些库具有通常命名的"仅供内部使用"命名空间aux,但它们旨在被用户隐藏(或至少被忽略).
这样可以更好地保留命名空间的优点:它们可以避免命名冲突.我可以(人们经常这样做,因为向量可以有几个不同的含义)定义我自己的vector类,它不会与之冲突 std::vector.
那么你的命名空间应该有多深层嵌套?我倾向于使用类似标准库的东西,加上一点.不要为所有内容创建新的命名空间,并保持命名空间名称简短.
也许你公司的所有代码都使用了一个共同的根命名空间Cpy.
在这种情况下,您可能会为每个产品设置一个命名空间Prod.过去那个?好吧,你可能有每个主要组件(Comp)的命名空间,基本上就是这样.
这里重要的是你几乎不必引用最外面的命名空间.您编写的代码将在内部Cpy::Prod,因此您需要输入的唯一名称空间前缀Comp::是简洁的,就像标准库一样std.我几乎从不必写Cpy::Prod::Comp,因为我的所有代码都已经在前两个命名空间内.如果不是这种情况,则命名空间结构太长且嵌套太深.
然后,我有时不喜欢加速,并创造小"内部"帮手命名空间,通常称为Aux或Util或相似.这些应该是小的,只能不断地从他们的直接父命名空间访问.特定组件可能有一些仅供内部使用的类.所以它们隐藏在一个小的Aux命名空间中,主要是为了让它们与引用我们组件的其他人隐藏起来.
当然,您可能会问自己,最外层的"公司"命名空间真正具有什么目的.是不是我们所有的代码都是,我们的公司?第三方代码通常(希望)在其自己的命名空间内(例如boost::),因此即使没有公司命名空间,我们也不应冒任何冲突的风险.您可能想要删除那个.
另一件需要考虑的事情是,如果您要编写库组件供外部使用,那么命名空间结构应该更短.在公司内部,您可以假设每个人都已在"公司"命名空间内编写代码,因此他们永远不必输入命名空间前缀.它基本上是"免费的".但是,如果外部用户必须引用您的代码,那么它们是一个额外的命名空间层,他们必须输入,这会很快变旧.整个"产品"命名空间可能是不可避免的(类似于std或boost),但您可能希望尽可能频繁地避免使用"产品"命名空间.(同样,像这两个一样,很少在根命名空间下创建子命名空间)
最重要的是,您的命名空间必须实用且可用.如果强制用户在命名空间前缀中键入超过8个字符,那就会很烦人,而且它们只会开始放在using namespace X任何地方.您只需要命名空间,否则可能会发生名称冲突.您控制的代码永远不应该与第三方代码共享命名空间,因为您无法控制它们添加的名称(通常,第三方库通过将其库放在公共根名称空间中来处理此问题,例如boost).但是在你控制的代码中,不会有那么多碰撞.因此,不要定义比实际需要更多的命名空间.
我认为这是非常主观的,你可能会收到很多不同的意见,所以这是我的!:)
嵌套命名空间——很好。一个大的命名空间——太可怕了。
以上是考虑到现实世界(即非常大的代码库)。为了防止 RSI,请考虑短命名空间名称!;)
编辑:一个例子,它非常主观,其他人会有不同的方法......
假设您在 foo 公司工作,在 Java 中,通常以 com 开头,因此请使用 foo
namespace foo
{
}
Run Code Online (Sandbox Code Playgroud)
现在您公司的所有代码都位于一个命名空间中,接下来考虑任何共享的内容:
namespace foo
{
namespace com
{
// any communication stuff goes here
namespace msg
{
// let's say you have some form of messages that you send
} // msg
namespace con
{
// wraps all your connectivity
} // con
} // com
namespace util
{
// utilities
// you may not need to break this up further
} // util
} // foo
Run Code Online (Sandbox Code Playgroud)
现在假设您有项目 bob,在项目中给它自己的命名空间
namespace foo
{
namespace proj
{
// all projects are here
namespace bob
{
// all bob's stuff is here, break it up as you need (though I wouldn't bother unless you have hundred's of classes where collisions are likely), I'd rather organise the files in the file system appropriately and keep the classes in the same namespace.
} // bob
} // proj
} // foo
Run Code Online (Sandbox Code Playgroud)