C + + 中的内部类型定义——好样式还是坏样式?

我发现自己最近经常做的事情是声明 typedef 与该类中的特定类相关,即。

class Lorem
{
typedef boost::shared_ptr<Lorem> ptr;
typedef std::vector<Lorem::ptr>  vector;


//
// ...
//
};

然后在代码的其他地方使用这些类型:

Lorem::vector lorems;
Lorem::ptr    lorem( new Lorem() );


lorems.push_back( lorem );

我喜欢它的原因:

  • 它降低了类模板引入的噪声,std::vector<Lorem>变成 Lorem::vector等。
  • 它作为一个意图的陈述——在上面的例子中,Lorem 类是通过 boost::shared_ptr计数的引用,并存储在一个向量中。
  • 它允许实现发生变化-也就是说,如果 Lorem 需要改变,以便在稍后阶段(通过 boost::intrusive_ptr)进行侵入性引用计数,那么这将对代码产生最小的影响。
  • 我认为它看起来“更漂亮”,而且可以说更容易阅读。

我不喜欢的原因:

  • 依赖关系有时会出现问题——比如,如果你想在另一个类中嵌入一个 Lorem::vector,但只需要(或想)转发声明 Lorem (而不是在其头文件中引入依赖关系) ,那么你最终必须使用显式类型(例如 boost::shared_ptr<Lorem>而不是 Lorem::ptr) ,这有点不一致。
  • 它可能不是很常见,因此更难理解?

我试图客观地对待我的编码风格,所以如果能得到一些其他的意见就好了,这样我就可以稍微剖析一下我的想法。

99501 次浏览

我建议把这些 typedef 移到课外。通过这种方式,您可以消除对共享指针和向量类的直接依赖,并且只有在需要时才能包含它们。除非您在类实现中使用这些类型,否则我认为它们不应该是内部 typedef。

您喜欢它的原因仍然匹配,因为它们是通过 typedef 的类型别名解决的,而不是通过在类中声明它们来解决的。

我认为这是极好的风格,我自己使用它。尽可能地限制名称的范围总是最好的,在 C + + 中使用类是实现这一点的最佳方法。例如,C++标准程式库在类中大量使用 typedef。

当 typedef 仅在类本身内使用时(即声明为 private) ,我认为这是一个好主意。但是,出于您给出的确切原因,如果 typedef 需要在类外部知道,我不会使用它。在这种情况下,我建议将他们转移到课外。

Typedefs 绝对是很好的风格,并且你所有的“我喜欢的理由”都是很好的和正确的。

关于你在这方面的问题。前向声明不是圣杯。您可以简单地设计代码以避免多级依赖关系。< br >

您可以将 typedef 移到类之外,但 Class: : ptr 比 ClassPtr 漂亮得多,所以我不这样做。对于我来说,这就像名称空间一样——事物在作用域内保持连接。

有时候是的

Trait<Loren>::ptr
Trait<Loren>::collection
Trait<Loren>::map

而且它可以是所有域类的默认值,并且对某些域类有一些特殊化。

STL 一直在做这种事情—— typedef 是 STL 中许多类的接口的一部分。

reference
iterator
size_type
value_type
etc...

所有 typedef 都是各种 STL 模板类接口的一部分。

Typedefs 是构建在 c + + 中的泛型,所以 c + + 中的类型化功能源于 Typedefs 本身。

再投一次赞成票,这是个好主意。我开始这样做的时候,写了一个模拟,必须是有效的,无论是在时间和空间。所有的值类型都有一个以提升共享指针开始的 Ptr typedef。然后,我进行了一些分析,并将其中一些改为一个升级侵入指针,而不必更改这些对象所使用的任何代码。

请注意,只有当您知道将在哪里使用这些类,并且所有的使用都具有相同的要求时,这种方法才能起作用。例如,我不会在库代码中使用它,因为在编写库时,您无法知道它将在哪个上下文中使用。

它作为一种意向声明- 在上面的例子中,Lorem 类 意欲被参考计数 : share _ ptr 并存储在 矢量

这正是 没有所做的。

如果我在代码中看到‘ Foo: : Ptr’,我完全不知道它是 share _ Ptr 还是 Foo * (STL 有: : 指针 typedefs,它是 T * ,记住)或者其他什么。如果它是一个共享指针,则 ESP.根本不提供 typedef,而是在代码中显式地使用 share _ ptr。

实际上,我很少在模板超编程之外使用 typedef。

STL 一直在做这类事情

STL 设计的概念是根据成员函数和嵌套类型定义的,这是一个历史的死胡同,现代模板库使用免费的函数和 trait 类(参见 Boost)。Graph) ,因为它们并不排除内置类型对概念进行建模,而且它使得在设计时没有考虑给定模板库的概念的类型更容易适应。

不要用 STL 作为犯同样错误的理由。

目前我正在研究代码,这些代码大量使用这类 typedef。

但是我注意到,通常存在迭代的 typedef,定义在几个类之间分离,并且您永远不会真正知道所处理的是什么类型。我的任务是总结隐藏在这些 typedef 之后的一些复杂数据结构的大小——因此我不能依赖于现有的接口。与三到六级嵌套名称空间结合使用,然后就会变得混乱。

因此,在使用它们之前,有一些要考虑的问题

  • 还有其他人需要这些 typedef 吗? 其他类是否经常使用这个类?
  • 我应该缩短用法还是隐藏类? (在隐藏的情况下,您还可以考虑接口。)
  • 还有其他人在使用代码吗?他们是怎么做到的?他们会认为这更容易还是会变得困惑?