我只是在教自己C++命名空间(来自C#背景),我真的开始认为,即使C++比大多数其他语言做得更好,嵌套命名空间也不是其中之一!
我是否正确地认为,为了声明一些嵌套的命名空间,我必须执行以下操作:
namespace tier1 { namespace tier2 { namespace tier3 { /* then start your normal code nesting */ } } }
相反:
namespace tier1::tier2::tier3 { }
àlaC#?
当我需要转发声明时,这变得更加疯狂:
namespace tier1 { namespace tier2 { namespace forward_declared_namespace { myType myVar; // forward declare } namespace tier3 { /* then start your normal code nesting */ class myClass { forward_declared_namespace::myType myMember; } } } }
请记住,我开发的典型系统包括:
MyCompany::MySolution::MyProject::System::[PossibleSections]::Type
这就是为什么你不倾向于在C++示例中看到很多名称空间的使用?或者通常只有单个(非嵌套)命名空间?
UPDATE
对于任何有兴趣的人,这就是我最终解决这个问题的方法.
C++命名空间并不是一种设计机制 - 它们只是为了防止名称冲突.您真的不希望或不需要在99.99%的情况下使用嵌套命名空间.
在C++中正确使用名称空间的一个很好的例子是C++标准库.这个相当大的库中的所有内容都放在一个名为std的命名空间中- 没有尝试或需要将库分解为(例如)I/O子命名空间,数学子命名空间,容器子命名空间等等
在C++中建模的基本工具是类(在某种程度上是模板),而不是命名空间.如果您觉得需要嵌套,则应考虑使用嵌套类,这些类与命名空间相比具有以下优点:
他们有方法
他们可以控制访问
他们不能重新开放
考虑到这些之后,如果您仍希望通过各种方式使用嵌套命名空间,那么以这种方式使用它们在技术上没有任何问题.
C++命名空间是对先前产品的巨大改进(即根本没有命名空间).C#命名空间扩展了概念并使用它运行.我建议你将命名空间保存在一个简单的扁平结构中.
编辑 您是否建议由于我在此概述的缺点?
只需"是".C++命名空间的设计不是为了帮助您按照C#中的方式对逻辑和库进行分区.
C++命名空间的目的是阻止C开发人员遇到的现实问题,当使用两个导出相同功能名称的第三方库时,他们会遇到名称冲突.C开发人员有各种解决方法,但它可能是一个严重的痛苦.
想法是STL等具有std::
命名空间,"XYZ Corp"提供的lib将具有xyz::
命名空间,您为"ABC corp"工作将把所有东西放在单个abc::
命名空间中.
前进声明时我做的是这样的:
namespace abc { namespace sub { namespace subsub { class MyClass; }}}
我的前瞻性声明被折叠成一行.前提声明的可读性被牺牲,以换取其余代码的可读性.对于定义,我也不使用缩进:
namespace abc { namespace sub { namespace subsub { class MyClass { public: MyClass(); void normalIntendationsHere() const; }; } } }
使用这种风格在开始时需要一些纪律,但这对我来说是最好的妥协.
至少作为一个小帮助,在某些情况下你可以这样做:
namespace foo = A::B::C::D;
然后引用A :: B :: C :: D作为foo.但仅在某些情况下.
你可以跳过缩进.我经常写
namespace myLib { namespace details { /* source code */ } } /* myLib::details */
C++源代码最终被编译成二进制文件,而C#/ Java则保留在二进制文件中.因此,命名空间只为变量命名冲突提供了一个很好的解决方案.它不适用于类层次结构.
我经常在代码中保留一个或两个命名空间级别.