2010-11-17 72 views
3

为纯粹的组织目的使用子命名空间会被认为是不好的做法吗?例如:组织不良实践的子命名空间?

namespace vehicles 
{ 
    namespace cars 
    { 
     // Stuff here 
    } 

    namespace boats 
    { 
     // More stuff here 
    } 
} 

我可以看到这将是对大项目的一个问题,因为这会带来不便键入vehicles::cars::function很多。但是,小项目呢?

+0

要看什么东西,更多的东西 – 2010-11-17 18:15:05

+0

另外请注意,在小程序中观察风格的唯一原因是适应大程序的预期。风格,良好的做法,设计模式等等在小程序中很少涉及,因为它们中的大多数用于易于维护和容易扩展 – 2010-11-17 18:16:52

回答

7

为什么在一个小型项目中输入vehicles::cars::function很不方便?

记住命名空间应该服务的目的。他们应该避免名称冲突,而不是其他。

如果你发明了这样一个令人费解的命名空间结构,我试图将几个using namespace ...放在每个文件的顶部,那么它就会破坏命名空间的目的。

它也没有告诉我很多我不知道已经。你打算在你的boats命名空间中放置什么,我不知道这个名字本身就是一艘船?我是否需要在命名空间中的任何内容上澄清“这属于船只”?很可能不会,然后命名空间没有意义。

一般情况下,不问什么问题与使用任何语言功能,直到你发现了优点是什么是。每个功能都需要证明自己。那么你提出的命名空间会解决什么问题?

如果它不能解决真正的实际问题,那么这是一个坏主意,不管别的。

我一直认为看看不同语言的标准库是有益的。

.NET使用长名称的深层嵌套命名空间。简单动态数组的全名是System.Collections.Generic.List<T>

因此,没有人使用命名空间。每个人只需将using System.Collections.Generic放置在需要使用List的每个文件的顶部。

正因为如此,遇到困难的那一刻你还会碰到另一个List class。你会想要做同样的事情,瞧,你有两个类冲突。

C++使用非常平坦的namespcae结构,其中名称空间的名称也很短。

C++中的等效类只是std::vector。因此,人们通常会输入名称空间前缀,因此,当我将另一个矢量类添加到我的项目中时,它会起作用。没有名称冲突,因为当我想引用标准库向量时,我使用前缀std::

+0

我会与“而不是其他”部分争论。我认为命名空间中最有价值的东西是ADL,并且可以将独立函数包含到类的接口中 – 2010-11-17 18:18:06

+0

@Armen:你也可以使用没有命名空间的类。最终,命名空间是*细分*你的代码。 ADL是一种避免这种情况的方式,将代码捆绑在一起。 – jalf 2010-11-17 18:19:04

+0

@Armen:但我同意ADL是使C++中的命名空间*工作*的重要组成部分。如果没有这些,我们最终可能最终会在C++中的任何地方放置'using namespace ...',否定命名空间的优点。 – jalf 2010-11-17 18:23:06

3

恕我直言,这不是不好的做法!还要考虑使用别名来避免必须每次输入完全限定名称,而不是在需要时注入整个名称空间......

2

命名空间的其中一个原因是为了组织目的,你如何使它们细化到个人偏好 - 我个人喜欢它们是相当通用的,例如我有TransferObjects。交通工具,但不是那么细致。除非你有很多很多类型,否则我没有看到详细说明。但这取决于你。

如果这是一个小项目,那么代码库应该相对较小并且易于导航,从而消除了对这种方法的需求?

4

那么,为了什么是值得的,我在几年前尝试在一个中等规模的项目上使用深层嵌套的命名空间,而且这绝对是地狱 - 我花了我的整个时间来编写typedefs :)在Java中,包工作得非常好,因为你可以在每个.java文件的顶部导入东西,而不会遇到大问题。在C++中,这是一个令人头疼的问题,因为在头文件中使用伪指令/声明是一种不好的做法 - 因此,您最终要么(a)使用头文件(bleurgh)或(b)完全限定所有内容大量的typedefs(也bleurgh)。不冷静 - 我的建议是,以避免瘟疫一样,除非你喜欢写的东西,如:

centipede::autoseg::hierarchygeneration::ragbuilders::RAGBuilder<...> 

这不是一个类型,它是一个句子......

+0

为什么你会使用typedefs呢?我认为'使用'指令将是正确的工具。当然你不会把它们放在页眉的顶部,但是你可以在本地使用它们,在函数内部,它们不会污染任何东西。如果你在一个函数中使用了很多东西,那么在函数的顶部放一个'using abcd :: efgh :: MyClass;'。另一种方法是使用本地'namespace po = boost :: program_options;'来缩写命名空间。 – Ela782 2015-06-30 14:05:42

+0

@ Ela782:你可以把函数放入函数中(尽管你必须在每个函数中重复它们),但是如果你这样做,你仍然不得不完全限定成员变量的类型。你可以在没有typedefs的情况下将你的类包装在一个虚拟的命名空间中,用using指令将它们导入到这个命名空间中,然后将你的类导回到封闭的命名空间中,但是这会变得有些诡异。命名空间的缩写可以起作用,但可以说阻碍了可读性的一点,并有助于解决您最初不存在的问题(over-nested namespaces)。 – 2015-07-01 00:22:54

+0

好的,我也同意你的最后一句话:-)你是什么意思与_“你仍然最终不得不完全限定成员变量的类型”_? – Ela782 2015-07-01 20:54:15