我在一个项目中广泛使用 shared_ptr 和 STL,这会导致类型过长、容易出错,例如 shared_ptr< vector< shared_ptr<const Foo> > >
(我偏爱是一名 ObjC 程序员,其中长名称是常态,但这仍然太多了。)我相信,始终将其称为 FooListPtr
会更清楚。并记录命名约定“Ptr”表示shared_ptr,“List”表示shared_ptr的 vector 。
这很容易 typedef,但它会导致标题令人头疼。我似乎有几个选项来定义 FooListPtr
:
- Foo.h.这会缠绕所有的 header 并造成严重的构建问题,因此它不是首发。
- FooFwd.h(“转发头”)。这就是 Effective C++ 所建议的,基于 iosfwd.h。这是非常一致的,但维护两倍数量的 header 的开销充其量似乎很烦人。
- Common.h(将它们全部放在一个文件中)。这通过缠绕许多不相关的类型而扼杀了可重用性。您现在不能只拿起一个对象并将其移动到另一个项目。这不是首发。
- typedef 的某种花哨的#define 魔法,如果它还没有被 typedef 过的话。我一直不喜欢预处理器,因为我认为它让新人难以理解代码,但也许....
- 使用 vector 子类而不是 typedef。这似乎很危险......
这里有最佳实践吗?当可重用性、可读性和一致性至关重要时,它们在实际代码中的表现如何?
如果其他人想添加其他讨论选项,我已标记此社区 wiki。
最佳答案
我正在编写一个听起来像是使用 common.h
方法的项目。它非常适合那个项目。
有一个名为 ForwardsDecl.h
的文件位于预编译的头文件中,它简单地向前声明了所有重要的类和必要的 typedef。在这种情况下,使用 unique_ptr
代替 shared_ptr
,但用法应该类似。它看起来像这样:
// Forward declarations
class ObjectA;
class ObjectB;
class ObjectC;
// List typedefs
typedef std::vector<std::unique_ptr<ObjectA>> ObjectAList;
typedef std::vector<std::unique_ptr<ObjectB>> ObjectBList;
typedef std::vector<std::unique_ptr<ObjectC>> ObjectCList;
Visual C++ 2010 接受此代码,即使这些类只是前向声明的(不需要完整的类定义,因此无需包含每个类的头文件)。我不知道这是否是标准的,其他编译器是否需要完整的类定义,但它不需要:另一个类(ObjectD)可以有一个 ObjectAList 作为成员,而不需要包含 ObjectA.h - 这可以真的有助于减少头文件依赖!
维护不是一个特别的问题,因为前向声明只需要编写一次,任何后续更改只需要在类的头文件中的完整声明中发生(这将触发更少的源文件重新编译由于减少了依赖)。
最后看来,这可以在项目之间共享(我自己没有尝试过),因为即使项目实际上没有声明 ObjectA,也没关系,因为它只是转发声明,如果你不使用它编译器不在乎。因此,该文件可以包含它所使用的所有项目中的类的名称,并且对于特定项目是否缺少某些类并不重要。所需要的只是必要的完整声明头(例如 ObjectA.h
)包含在任何实际使用的 source (.cpp) 文件中他们。
关于c++ - typedef 的头文件最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2356548/