C++ 中的内部类型定义——好的风格还是坏的风格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/759512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Internal typedefs in C++ - good style or bad style?
提问by Will Baker
Something I have found myself doing often lately is declaring typedefs relevant to a particular class inside that class, i.e.
我发现自己最近经常做的事情是声明与该类中的特定类相关的 typedef,即
class Lorem
{
typedef boost::shared_ptr<Lorem> ptr;
typedef std::vector<Lorem::ptr> vector;
//
// ...
//
};
These types are then used elsewhere in the code:
然后在代码的其他地方使用这些类型:
Lorem::vector lorems;
Lorem::ptr lorem( new Lorem() );
lorems.push_back( lorem );
Reasons I like it:
我喜欢它的原因:
- It reduces the noise introduced by the class templates,
std::vector<Lorem>
becomesLorem::vector
, etc. - It serves as a statement of intent - in the example above, the Lorem class is intended to be reference counted via
boost::shared_ptr
and stored in a vector. - It allows the implementation to change - i.e. if Lorem needed to be changed to be intrusively reference counted (via
boost::intrusive_ptr
) at a later stage then this would have minimal impact to the code. - I think it looks 'prettier' and is arguably easier to read.
- 它减少了类模板引入的噪音,
std::vector<Lorem>
变成Lorem::vector
等。 - 它用作意图声明 - 在上面的示例中,Lorem 类旨在通过引用计数
boost::shared_ptr
并存储在向量中。 - 它允许更改实现 - 即,如果 Lorem 需要
boost::intrusive_ptr
在稍后阶段更改为侵入式引用计数(通过),那么这对代码的影响最小。 - 我认为它看起来“更漂亮”并且可以说更容易阅读。
Reasons I don't like it:
我不喜欢的原因:
- There are sometimes issues with dependencies - if you want to embed, say, a
Lorem::vector
within another class but only need (or want) to forward declare Lorem (as opposed to introducing a dependency on its header file) then you end up having to use the explicit types (e.g.boost::shared_ptr<Lorem>
rather thanLorem::ptr
), which is a little inconsistent. - It may not be very common, and hence harder to understand?
- 有时存在依赖关系的问题——如果你想
Lorem::vector
在另一个类中嵌入一个,但只需要(或想要)转发声明 Lorem(而不是引入对其头文件的依赖),那么你最终不得不使用显式类型(例如boost::shared_ptr<Lorem>
而不是Lorem::ptr
),这有点不一致。 - 它可能不是很常见,因此更难理解?
I try to be objective with my coding style, so it would be good to get some other opinions on it so I can dissect my thinking a little bit.
我尽量客观地对待我的编码风格,所以最好能得到一些其他的意见,这样我就可以稍微剖析一下我的想法。
采纳答案by Will Baker
I think it is excellent style, and I use it myself. It is always best to limit the scope of names as much as possible, and use of classes is the best way to do this in C++. For example, the C++ Standard library makes heavy use of typedefs within classes.
我认为它是优秀的风格,我自己使用它。尽可能地限制名称的范围总是最好的,在 C++ 中使用类是最好的方法。例如,C++ 标准库在类中大量使用 typedef。
回答by Marc Mutz - mmutz
It serves as a statement of intent - in the example above, the Lorem class is intended to be reference counted via boost::shared_ptr and stored in a vector.
它用作意图声明 - 在上面的示例中,Lorem 类旨在通过 boost::shared_ptr 进行引用计数并存储在向量中。
This is exactly what it does notdo.
这正是它并没有这样做。
If I see 'Foo::Ptr' in the code, I have absolutely no idea whether it's a shared_ptr or a Foo* (STL has ::pointer typedefs that are T*, remember) or whatever. Esp.if it's a shared pointer, I don't provide a typedef at all, but keep the shared_ptr use explicitly in the code.
如果我在代码中看到 'Foo::Ptr',我完全不知道它是 shared_ptr 还是 Foo*(STL 有 ::pointer typedefs 是 T*,记住)或其他什么。特别是 如果它是一个共享指针,我根本不提供 typedef,但在代码中明确使用 shared_ptr。
Actually, I hardly ever use typedefs outside Template Metaprogramming.
实际上,我几乎从不使用模板元编程之外的 typedef。
The STL does this type of thing all the time
STL 一直在做这种事情
The STL design with concepts defined in terms of member functions and nested typedefs is a historical cul-de-sac, modern template libraries use free functions and traits classes (cf. Boost.Graph), because these do not exclude built-in types from modelling the concept and because it makes adapting types that were not designed with the given template libraries' concepts in mind easier.
根据成员函数和嵌套 typedef 定义概念的 STL 设计是一个历史死胡同,现代模板库使用自由函数和特征类(参见 Boost.Graph),因为这些不排除内置类型对概念进行建模,因为它可以更轻松地调整未根据给定模板库的概念设计的类型。
Don't use the STL as a reason to make the same mistakes.
不要使用 STL 作为犯同样错误的理由。
回答by ?zgür
Typedefs are the ones what policy based design and traitsbuilt upon in C++, so The power of Generic Programming in C++ stems from typedefs themselves.
Typedef 是C++ 中基于策略的设计和特征构建的那些,因此 C++ 中通用编程的力量源于 typedef 本身。
回答by Mykola Golubyev
Typdefs are definitely are good style. And all your "reasons I like" are good and correct.
Typdefs 绝对是很好的风格。你所有的“我喜欢的理由”都是好的和正确的。
About problems you have with that. Well, forward declaration is not a holy grail. You can simply design your code to avoid multi level dependencies.
关于你遇到的问题。好吧,预先声明不是圣杯。您可以简单地设计代码以避免多级依赖。
You can move typedef outside the class but Class::ptr is so much prettier then ClassPtr that I don't do this. It is like with namespaces as for me - things stay connected within the scope.
您可以将 typedef 移到类之外,但 Class::ptr 比 ClassPtr 漂亮得多,我不这样做。对我来说就像命名空间一样 - 事情在范围内保持联系。
Sometimes I did
有时我做
Trait<Loren>::ptr
Trait<Loren>::collection
Trait<Loren>::map
And it can be default for all domain classes and with some specialization for certain ones.
它可以是所有领域类的默认值,并且对某些领域有一些特殊化。
回答by Michael Burr
The STL does this type of thing all the time - the typedefs are part of the interface for many classes in the STL.
STL 一直在做这种事情——typedef 是 STL 中许多类的接口的一部分。
reference
iterator
size_type
value_type
etc...
are all typedefs that are part of the interface for various STL template classes.
都是 typedef,它们是各种 STL 模板类的接口的一部分。
回答by KeithB
Another vote for this being a good idea. I started doing this when writing a simulation that had to be efficient, both in time and space. All of the value types had an Ptr typedef that started out as a boost shared pointer. I then did some profiling and changed some of them to a boost intrusive pointer without having to change any of the code where these objects were used.
另一个投票赞成这是一个好主意。我在编写一个必须在时间和空间上都有效的模拟时开始这样做。所有的值类型都有一个 Ptr typedef,它开始是一个 boost 共享指针。然后我做了一些分析并将其中一些更改为 boost 侵入式指针,而无需更改使用这些对象的任何代码。
Note that this only works when you know where the classes are going to be used, and that all the uses have the same requirements. I wouldn't use this in library code, for example, because you can't know when writing the library the context in which it will be used.
请注意,这仅在您知道将要使用的类的位置时才有效,并且所有用途都具有相同的要求。例如,我不会在库代码中使用它,因为在编写库时您无法知道它将被使用的上下文。
回答by Bodo
Currently I'm working on code, that intensively uses these kind of typedefs. So far that is fine.
目前我正在编写代码,大量使用这些类型的定义。到目前为止还好。
But I noticed that there are quite often iterative typedefs, the definitions are split among several classes, and you never really know what type you are dealing with. My task is to summarize the size of some complex data structures hidden behind these typedefs - so I can't rely on existing interfaces. In combination with three to six levels of nested namespaces and then it becomes confusing.
但是我注意到经常有迭代 typedef,定义被分成几个类,你永远不知道你在处理什么类型。我的任务是总结隐藏在这些 typedef 后面的一些复杂数据结构的大小 - 所以我不能依赖现有的接口。结合三到六级嵌套命名空间,然后它变得混乱。
So before using them, there are some points to be considered
所以在使用它们之前,有一些要点需要考虑
- Does anyone else need these typedefs? Is the class used a lot by other classes?
- Do I shorten the usage or hide the class? (In case of hiding you also could think of interfaces.)
- Are other people working with the code? How do they do it? Will they think it is easier or will they become confused?
- 还有其他人需要这些 typedef 吗?该类是否被其他类大量使用?
- 我是缩短使用时间还是隐藏课程?(在隐藏的情况下,您也可以考虑接口。)
- 其他人是否在使用代码?他们是怎么做到的呢?他们会认为这更容易还是会感到困惑?
回答by C?t?lin Piti?
I recommend to move those typedefs outside the class. This way, you remove direct dependency on shared pointer and vector classes and you can include them only when needed. Unless you are using those types in your class implementation, I consider they shouldn't be inner typedefs.
我建议将这些 typedef 移到课堂之外。通过这种方式,您可以消除对共享指针和向量类的直接依赖,并且仅在需要时才可以包含它们。除非您在类实现中使用这些类型,否则我认为它们不应该是内部 typedef。
The reasons you like it are still matched, since they are solved by the type aliasing through typedef, not by declaring them inside your class.
你喜欢它的原因仍然匹配,因为它们是通过 typedef 的类型别名解决的,而不是通过在你的类中声明它们。
回答by Stefan R?dstr?m
When the typedef is used only within the class itself (i.e. is declared as private) I think its a good idea. However, for exactly the reasons you give, I would not use it if the typedef's need to be known outside the class. In that case I recommend to move them outside the class.
当 typedef 仅在类本身中使用(即声明为私有)时,我认为这是一个好主意。但是,正是出于您给出的原因,如果需要在课堂之外知道 typedef,我不会使用它。在这种情况下,我建议将它们移到课外。