在C ++项目中为每个.h创建一个.cpp是一个好习惯吗?

时间:2009-10-29 17:28:08

标签: c++ compilation header-files

某些类(如异常或模板)只需要头文件(.h),通常没有与之相关的.cpp。

我已经看到一些项目(对于某些类)没有与头文件关联的任何.cpp文件,可能是因为实现很短,直接在.h中完成,或者可能是出于其他原因,例如模板类,必须在头文件中包含实现。

您的意见是什么,如果一个类太短,我是否应该避免创建.cpp文件并直接在头文件上编写代码?如果代码写在头文件中,我是否应该包含一个空的.cpp,以便项目中的文件保持一致?

9 个答案:

答案 0 :(得分:14)

我不会添加不必要的.cpp文件。您添加的每个.cpp文件都必须编译,这只会减慢构建过程。

一般来说,使用你的类只需要头文件 - 我认为“空”.cpp文件没有优势,以保证项目的一致性。

答案 1 :(得分:8)

不。如果.cpp中没有任何内容,则不需要。

答案 2 :(得分:4)

总是为每个.h创建.cpp有一个好处,即使前者是空的:它在编译时强制执行头文件是自包含的。这与foo.cpp中首先包含foo.h的guideline有关:

  

使用首选顺序,如果dir2 / foo2.h省略了任何必要的包含,则dir / foo.cpp的构建将中断。因此,此规则确保构建中断首先显示在处理这些文件的人身上,而不是其他包中的无辜人员。

答案 3 :(得分:3)

它真的是马匹的课程:

  • 仅限标题类:例如模板 类
  • Header和cpp:分隔声明 来自实施。
  • cpp only:你的main()可以住在一个 这些。

仅头文件源代码有时是编写可重用模板的唯一方法。有关这方面的大量示例,请参阅boost

标题和cpp更“正常”。它将声明与实现分开,并且当编译器不必多次读取实现时可以加快编译速度。你可能想从这里开始,然后看看实现是如何进行的,如果cpp文件变空,你可以删除它 另一点是,您将#include "foo.h"放在foo.cpp的顶部,以证明其他任何人都可以执行此操作而不会出现编译错误。

仅限Cpp文件。 main()可以在这里生存,我把cppUnit测试类放在这样的文件中。

答案 4 :(得分:1)

经验法则,将相关类保存在同一个文件中。主要不同的类需要放入他们自己的.hpp和.cpp文件中。这样做的原因是在大型项目中你有多达10,000个类,并且在用户面前放置那么多文件,IDE通常会让事情破裂。

答案 5 :(得分:1)

非常有用且成功的库,如boost中的许多库,只是标题库。

答案 6 :(得分:1)

如果某些类很短并且似乎是可以内联的,我倾向于将它们全部放在types.h中 - 这是我认为不值得.cpp文件的唯一标题。

然而,大多数课程都超出了仅进入标题的机会,以及进入types.h的机会。

我做的一些例子。我认为实现三维向量Vector3的类应该得到它的.h和.cpp,尽管很简单。但Position并不值得这样做;毕竟,它甚至可能是P.O.D.结构,如果它不是我喜欢在那里实施的那个讨厌的getDistance()

所以不 - 并非所有课程都应该得到他们的.cpp和.h文件。但大多数人都这样做,而那些并非绝对不能站在单独头球中的人。如果它们如此短暂以至于不能单独插入标题,要么它们与其他短级课程一起拥抱,要么进入与他们密切相关的课程的标题。

答案 7 :(得分:1)

我的经验法则是,我需要多行代码表达的任何方法都会进入.cpp文件。

有关此问题的进一步讨论,您可能需要查看我的这个老问题:C++ code in header files。我不认为你的问题是完全重复的,但它足够接近你应该阅读它。

答案 8 :(得分:1)

另请参阅this question - 头文件只应用于声明。

如果您有多个位置包含可编译的代码(来自您的评论:“我应该避免创建.cpp文件并直接在头文件上编写代码吗?”),它将每次编译(尽管您可能有预编译的头文件,链接器将解析(或不解析)膨胀的对象代码。

仅仅因为类定义很小并不意味着它应该在头文件中,除非定义也与声明相同 - 例如一个纯虚拟类或另一个答案中提到的简单类型。