类VERSUS命名空间或类和命名空间? [关闭](Class VERSUS namespace,

2019-08-07 11:31发布

这两个类和命名空间?

这个问题是关于我看到自己使用的模式越来越多:既具有类和相关概念命名空间。 我认为这主要动机是C ++语言的文物,但不完全。

我想顶级的问题是:这是一个好主意? 既具有类和相关概念命名空间?

低级别的问题:

做这个的最好方式是什么?

嵌套在名称空间内类?:

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

或者单独,同行,类和命名空间?:

class Foo_Class {
    ...
};
namespace Foo_Namespace {
   // non-class free functions, etc.
}

我必须承认,我对命名空间内嵌套类倾斜。 尽管它会导致难看的名字。 但是,即使我这样做,我应该用什么样的命名约定:

以下是太长,导致真丑名Foo_Namespace :: Foo_Class

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

这是没有必要使用任何后缀或指标的名称:

namespace Foo {
   class Foo {
       ...
   };
}

但后来我发现自己不确定的,当我看着富::酒吧(),如果这是一个免费的功能条中的命名空间::美孚,即::富::酒吧(),或在命名空间类Foo的成员函数::富::富::酒吧()。

而像::富::富::酒吧名字仍然不是,嗯,不错。

目前,我做

这是没有必要使用任何后缀或指标的名称:

namespace Foo_ns {
   class Foo {
       ...
   };
}

主要是因为我一般是先创建类,再后来认识到,一个命名空间将是很好。

我不知道我是否应该恢复我已经很多年没有使用的命名约定:_c类,_ns的命名空间:

namespace Foo_ns {
   class Foo_c {
       ...
   };
}

细节:

我不想重复我上面已经说过,但我会添加更多一点。

据我所知,除了一个类中使用一个命名空间的最实际的原因是,你被允许做的免费功能的前置声明命名空间中的,但你不能做向前的一类的一些方法声明。 一类,即你必须声明它全有或全无。 而与一般的免费功能,并在特定的命名空间免费功能,您可以零碎声明。 零部件可以在不同的头文件中声明。 而不是#包括一个巨大的头,只有库进行大规模的类,你可以使用前置声明只是一个或两个功能。 等等。

(参见,例如, http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Forward_Declarations ,虽然谷歌netly归结相对正向声明而非包括头部)。

另一个原因是,一个命名空间允许类本身保持较小。

一类最大的优点是一类可以传递给一个模板,而命名空间是不可能的。

我喜欢有嵌套在命名空间中的类,Foo_ns / Foo_ns :: Foo_c,而不是让他们成为同行Foo_ns / Foo_c,因为经常一类需要辅助类,如Foo_ns / Foo_ns :: Foo_c / Foo_ns :: Foo_Helper_c。 如果类和命名空间是对等的,这似乎很奇怪有Foo_ns / Foo_c但Foo_ns :: Foo_Helper_c。

我喜欢的命名空间,因为我与安德烈Alexandresciu同意: http://laser.inf.ethz.ch/2012/slides/Alexandrescu/1-C++%20course%20parts%201%20and%202.pdf

 Class methods vs. free functions

 • Conventional wisdom: methods are cool, free functions are so 1960s
 • Yet:
   ◦ Free functions improve encapsulation over methods
   ◦ Free functions may be more general
   ◦ Free functions decouple better
   ◦ Free functions support conversions on their left-hand argument

  Surprising fact #2

    Making a function a method should be
    your last, not first, choice

  (c) 2012– Andrei Alexandrescu. 32 / 59

这比在类的方法来创建免费的功能。

但有时仅仅类必须使用 - 例如用于模板。

命名约定明智

我用Foo_ns / Foo_ns :: Foo_c过去

我使用Foo_ns / Foo_ns ::现在富

(顺便说一句,我倾向于使用Class_Names_With_Underscores_and_Initial_Caps,没有驼峰。)

如果这是有道理的,我可能会在的Elid命名空间中_ns后缀 - 例如,在空间和类(ES)不需要具有相同的名称。

我不喜欢让他们具有相同的名称。 考虑命名空间FOO内部类Foo构造函数:

::富::富::美孚()与:: Foo_ns ::富::美孚()

后者不是要好得多,但少了几分扑朔迷离。

我认为,我通常会创建其自己的阶级,没有命名空间嵌套它。 事实上,我可能添加了一些静态方法,之前我意识到嵌套在命名空间中的类会更好。 通过该阶段可以是重构一个疼痛,我有时最终创建转发功能,即从类静态方法前进到自由功能在命名空间,或反之亦然。 这使我后悔僵尸跳级wthin命名空间从第1步的权利。

结论

我现在的BKM是Foo_ns / Foo_ns ::美孚,即

namespace Foo_ns {
   class Foo { 
   ...
   };
}

我会很感激任何建议,任何改进。

还是我打破了这样做呢?

Answer 1:

我建议具有与相关功能的命名空间类。 一个很大的原因是参数相关查找 (ADL)。 当你调用具有类类型参数的非成员函数,函数名称是在类的封闭命名空间抬头。 所以,如果你有,说:

namespace foo {
  class bar { };
  void baz(bar);
}

如果你想打电话给baz ,你会不会需要明确地给它包含在命名空间中,你可以简单地做:

foo::bar x;
baz(x);

如果没有符合条件的baz ,编译器仍然发现的功能,因为它是包围它的参数的类型命名空间内。 以这种方式,C ++认为类的封闭命名空间的内容是类的接口的一部分。 实现这是一类以这种方式非成员非友元函数的接口的一部分功能,使ADL找到的功能, 增加了封装 。 如果函数并不需要访问一个类的内部,不让它该类的成员-相反,把它放在同一个命名空间为类。

这是怀疑你的命名空间具有相同的名称为您的类,但是。 通常会有一个命名空间内的多个类,即使有没有,名字就不同了。 命名空间的名称应该描述其内容,而不是它里面的单个类。



Answer 2:

独立 Foo_ClassFoo_Namespace肯定是不对的,它会阻止你使用参数相关的查找,以查找该是为了与类使用的命名空间功能。

所以类应该命名空间内嵌套是否会有服用类类型的参数命名空间中的功能。

为类和命名空间使用相同的名称比较混乱,可能导致在某些情况下歧义。

这也是不寻常的名称与一个首字母大写命名空间。 如果您的类名称以大写字母开头,你可以去命名foo和一类Foo ,给foo::Foo

是命名空间不会包含不止一个类的更多? 这听起来不寻常的给我。 我会说出其所有内容后的命名空间,只是没有一个类型。 如果它是一个socket类我把它放在一个networking的命名空间,例如。

我认为_c的类后缀是完全荒谬的。 我不喜欢_ns名称空间的后缀或者,它唯一的救命之恩将是Foo_ns::Foo优于Foo::Foo ,但我还是让foo::Foo代替。

(你的问题的其余部分只是似乎是“为什么命名空间的好”,这不应该真正需要解释,他们被添加到语言是有原因的,并使用非成员的接口部分好的建议其不要“T必须是会员。谷歌是正确的,在一般使用没有头向前声明,这并不能改变事实,你可以重新打开在单独的标题命名空间的新名称添加到命名空间,这是你的优势”重新描述。)



Answer 3:

我不喜欢“分形”的名字重复的东西,尽量避免它。 对于你的情况,我会尝试像命名空间“foo”和嵌套类“类型”。 也许一些其他的名字会更合适,但是这取决于你的实际使用情况。 下面是我发现自己重复一遍又一遍的使用情况:

namespace status {
    enum type {
        invalid,
        okay,
        on_fire
    };
    // debug output helper
    char const* to_string(type t);
}

枚举类型被称为status::type ,它可以采取类似值status::okay 。 漂亮可读恕我直言。



文章来源: Class VERSUS namespace, OR class AND namespace? [closed]