类VERSUS命名空间,还是类AND命名空间? [英] Class VERSUS namespace, OR class AND namespace?

查看:110
本文介绍了类VERSUS命名空间,还是类AND命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类和命名空间?

这个问题是关于一种我正在越来越多地使用自己的模式的问题:同时具有用于相关概念的类和名称空间.我认为这主要是由C ++语言工件引起的,但不是全部.

This question is about a pattern that I am seeing myself use more and more: Having both a class and a namespace for related concepts. I think this is motivated mainly by C++ language artifacts, but not totally.

我想最主要的问题是:这是一个好主意吗?拥有相关概念的类和名称空间吗?

I suppose the top level question is: Is this a good idea? Having both a class and a namespace for related concepts?

较低级别的问题:

做到这一点的最佳方法是什么?

What is the best way to do this?

嵌套在名称空间中的类?:

Class nested within the namespace?:

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

还是单独的,同级,类和名称空间?:

Or separate, peer, class and namespace?:

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

我必须承认,我倾向于将类嵌套在名称空间中. 即使导致丑陋的名字. 但是,即使我这样做,也应该使用什么命名约定:

I must admit that I lean towards nesting the class within the namespace. Even though it leads to ugly names. But even if I do that, what naming conventions should I use:

以下内容太长,导致名称Foo_Namespace :: Foo_Class非常丑陋

The following is too long, leading to really ugly names Foo_Namespace::Foo_Class

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

不必在名称中使用任何后缀或指示符:

It isn't necessary to use any suffixes or indicators in the name:

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

但是当我查看Foo :: bar()时,如果是命名空间:: Foo中的自由函数栏(即:: Foo :: bar())或类中的成员函数,我发现自己不确定Foo在命名空间:: Foo :: Foo :: bar()中.

But then I find myself uncertain, when I look at Foo::bar(), if that is a free function bar in namespace ::Foo, i.e. ::Foo::bar(), or a member function in class Foo in namespace ::Foo::Foo::bar().

和:: Foo :: Foo :: bar之类的名字仍然不是,嗯,很好.

And names like ::Foo::Foo::bar are still not, umm, nice.

我现在正在做

不必在名称中使用任何后缀或指示符:

It isn't necessary to use any suffixes or indicators in the name:

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

主要是因为我通常先创建类,然后再意识到命名空间会很好.

mainly because I usually create the class first, and then later realize that a namespace would be nice.

我想知道是否应该恢复多年来未使用的命名约定:_c用于类,_ns用于名称空间:

I wonder if I should revive a naming convention I haven't used in years: _c for class, _ns for namespaces:

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

详细信息:

我不会重复上面的内容,但我会再补充一点.

I won't repeat what I have said above, but I'll add a bit more.

我知道除了使用类之外,还使用名称空间的最实际的原因是允许您对名称空间中的自由函数进行前向声明,但不允许您对类的某些方法进行前向声明. IE.使用类,您必须声明全部或全部.尽管通常使用自由函数,尤其是使用命名空间中的自由函数,但您可以将其逐个声明.零件可以在不同的头文件中声明.您可以仅对一个或两个函数使用前向声明,而不是#为大规模类包括大规模的仅标头库.等等.

The most practical reason I know of to use a namespace in addition to a class is that you are allowed to do forward declarations of free functions in a namespace, but you are not allowed to do forward declarations of some methods of a class. I.e. with a class you have to declare it all or nothing. Whereas with free functions in general, and free functions in namespaces in particular, you can declare it piecemeal. Parts can be declared in different header files. Rather than #including a massive header-only-library for a massive class, you can use forward declarations for just one or two functions. Etc.

(例如,参见 http://google-styleguide.googlecode.com/svn /trunk/cppguide.xml#Forward_Declarations ,尽管Google坚决反对使用前向声明,而不是使用标头.)

(See, for example, http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Forward_Declarations, although Google netly comes down against forward declarations rather than including a header.)

另一个原因是,名称空间使类本身保持较小.

Another reason is that a namespace allows the class itself to be kept small.

类的最大优点是可以将类传递给模板,而不能将名称空间传递给模板.

The biggest advantage for a class is that a class can be passed to a template, whereas a namespace cannot be.

我更喜欢将类嵌套在命名空间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似乎很奇怪.

I prefer to have the class nested within the namespace, Foo_ns/Foo_ns::Foo_c rather than to have them as peers Foo_ns/Foo_c, because often a class needs helper classes, e.g. Foo_ns/Foo_ns::Foo_c/Foo_ns::Foo_Helper_c. If the class and the namespace are peers, it seems strange to have Foo_ns/Foo_c but Foo_ns::Foo_Helper_c.

我喜欢命名空间,因为我同意Andrei Alexandresciu:

I like namespaces, because I agree with Andrei 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

创建自由函数比在类中创建方法要好.

It's better to create free functions than methods in classes.

但是有时只需要使用类-例如模板.

But sometimes classes just have to be used - e.g. for templates.

明智地使用命名约定

我过去曾经使用过Foo_ns/Foo_ns :: Foo_c

I used Foo_ns / Foo_ns::Foo_c in the past

我正在使用Foo_ns/Foo_ns :: Foo

I'm using Foo_ns / Foo_ns::Foo now

(顺便说一句,我倾向于使用Class_Names_With_Underscores_and_Initial_Caps,而不是CamelCase.)

(By the way, I tend to use Class_Names_With_Underscores_and_Initial_Caps, not CamelCase.)

如果有道理,我可以忽略命名空间中的_ns后缀-例如命名空间和类不需要相同的名称.

If it makes sense, I might elide the _ns suffix on the namespace - e.g. where the namespace and the class(es) do not need to have the same name.

我不喜欢让他们使用相同的名字.考虑命名空间foo中的类Foo的构造函数:

I dislike making them having the same name. Consider a constructor for a class Foo inside a namespace foo:

:: Foo :: Foo :: Foo() 与 :: Foo_ns :: Foo :: Foo()

::Foo::Foo::Foo() vs ::Foo_ns::Foo::Foo()

后者并没有更好,但是却少了一些混乱.

The latter is not much better, but is a bit less confusing.

我认为通常我自己创建类,而不将其嵌套在名称空间中. 实际上,在意识到嵌套在名称空间中的类会更好之前,我可能添加了一些静态方法.到那个阶段,重构可能会很痛苦,而且我有时最终会创建转发功能,该功能从类静态方法转发到名称空间中的free函数,反之亦然.这使我后悔机器人从第1步跳到类wthin名称空间.

I think that I usually create the class on its own, without nesting it in a namespace. In fact, I probably add a few static methods, before I realize that a class nested within a namespace would be better. By that stage it may be a pain to refactor, and I sometimes end up creating forwarding functions, that forward from the class static method to the free function in the namespace, or vice versa. This causes me to regret bot to jump to class wthin namespace right from step 1.

结论

我当前的BKM是Foo_ns/Foo_ns :: Foo,即

My current BKM is Foo_ns / Foo_ns::Foo, i.e.

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

我将对您提出的任何建议,任何改进表示感谢.

I'd appreciate any suggestions, any improvements.

或者我只是因为这样做而被打破了吗?

Or am I just broken for doing this?

推荐答案

我建议您将类放在具有相关功能的名称空间中.造成这种情况的主要原因是依赖于参数的查找(ADL).当您调用具有类类型参数的非成员函数时,将在该类的封闭名称空间中查找该函数名.所以,如果有的话,说:

I recommend having your class in a namespace with related functions. A big reason for this is argument-dependent lookup (ADL). When you call a non-member function that has a class type argument, the function name is looked up in the enclosing namespace of that class. So if you have, say:

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

如果您要调用baz,则无需显式给出其包含的名称空间,只需执行以下操作即可:

If you ever want to call baz, you won't need to explicitly give the namespace it is contained in, you can simply do:

foo::bar x;
baz(x);

在没有限定baz的情况下,编译器仍找到该函数,因为该函数位于包含其参数类型的名称空间中.这样,C ++会将类的封闭名称空间的内容视为该类接口的一部分.这样,将作为类的接口一部分的函数实现为非成员非友元函数,从而允许ADL查找该函数

Without qualifying baz, the compiler still found the function because it is within a namespace that encloses the type of its argument. In this way, C++ considers the contents of the enclosing namespace of a class to be part of the interface of that class. Implementing functions that are part of the interface of a class as non-member non-friend functions in this way, allowing ADL to find the function, increases encapsulation. If a function doesn't need access to the internals of a class, don't make it a member of that class - instead, put it in the same namespace as that class.

可疑的是,您的名称空间与您的类具有相同的名称.通常,一个命名空间中将有多个类,即使没有,名称也将有所不同.命名空间的名称应描述其内容,而不仅仅是内部的单个类.

It's suspicious that your namespace has the same name as your class, however. Usually there will be more than one class within a namespace, and even if there weren't, the names would be different. The name of the namespace should describe its contents, not just the single class inside it.

这篇关于类VERSUS命名空间,还是类AND命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆