有些类,如异常或模板,只需要头文件 (.h),通常没有与它们相关的 .cpp。
我已经看到一些项目(对于某些类)没有任何与头文件关联的 .cpp 文件,可能是因为实现太短以至于直接在 .h 中完成,或者可能出于其他原因,例如模板类,其中必须在标头中包含实现。
你怎么看,如果一个类太短,我应该避免创建一个 .cpp 文件并直接在头文件上编写代码吗?如果代码写在头文件中,我是否应该包含一个空的 .cpp 以便项目中的文件保持一致?
有些类,如异常或模板,只需要头文件 (.h),通常没有与它们相关的 .cpp。
我已经看到一些项目(对于某些类)没有任何与头文件关联的 .cpp 文件,可能是因为实现太短以至于直接在 .h 中完成,或者可能出于其他原因,例如模板类,其中必须在标头中包含实现。
你怎么看,如果一个类太短,我应该避免创建一个 .cpp 文件并直接在头文件上编写代码吗?如果代码写在头文件中,我是否应该包含一个空的 .cpp 以便项目中的文件保持一致?
我不会添加不必要的 .cpp 文件。您添加的每个 .cpp 文件都必须进行编译,这只会减慢构建过程。
一般来说,无论如何,使用你的类只需要头文件 - 我认为“空” .cpp 文件对于项目的一致性没有任何好处。
没有。如果 .cpp 中不需要任何内容,则不需要。
始终为每个 .h 创建一个 .cpp 有一个优点,即使前者为空:它在编译时强制头文件是自包含的。这与在 foo.cpp 中首先包含 foo.h的准则有关:
使用首选顺序,如果 dir2/foo2.h 省略了任何必要的包含,则 dir/foo.cpp 的构建将中断。因此,此规则确保构建中断首先出现在处理这些文件的人员身上,而不是其他软件包中的无辜人员。
它真的很适合课程:
仅头文件源代码有时是编写可重用模板的唯一方法。有关此方面的大量示例,请参见boost。
标头和 cpp 更“正常”。它将声明与实现分开,并且在编译器不必多次读取实现负载时可以加快编译速度。你可能想从这里开始,然后看看实现是如何进行的,如果 cpp 文件为空,你可以删除它。
这里的另一点是,您将#include "foo.h"
在顶部foo.cpp
证明其他任何人都可以做到这一点并且没有编译器错误。
仅 Cpp 文件。main() 可以住在这里,我已经将 cppUnit 测试类放在这样的文件中。
经验法则,将相关类放在同一个文件中。主要不同的类需要放入自己的 .hpp 和 .cpp 文件中。这样做的原因是在大型项目中,您有多达 10,000 个类,并且将这么多文件放在用户和 IDE 面前通常会使事情中断。
有一些非常有用和成功的库,就像boost中的许多库一样,它们都是仅标头的。
如果某些类很短并且似乎是可内联的,我倾向于将它们全部放在一起types.h
——我认为唯一不值得 .cpp 文件的标题。
但是,大多数课程都超出了仅进入标题的机会和进入types.h
.
我所做的一些例子。Vector3
尽管很简单,但我认为实现 3D 向量的类值得其 .h 和 .cpp。但Position
并不真正值得这样做;毕竟,如果不是因为getDistance()
我喜欢在那里实现的那个讨厌的东西,它甚至会是一个 POD 结构。
所以不——不是所有的类都应该拥有它们的 .cpp 和 .h 文件。但是大多数人都这样做,而那些不确定的人绝对不会站在一个单独的头球中。如果它们太短而无法单独放入标题中,则它们要么与其他短类抱在一起,要么进入与它们密切相关的类的标题中。
我的经验法则是,我需要多于一行代码来表达的任何方法都会放入一个.cpp
文件中。
有关此问题的进一步讨论,您可能想查看我的这个老问题:头文件中的 C++ 代码。我不认为你的问题是完全重复的,但它足够接近你应该阅读它。
另请参阅此问题- 头文件应仅用于声明。
如果您在多个位置包含可编译代码(来自您的评论:“我应该避免创建 .cpp 文件并直接在头文件中编写代码吗?”),每次都会编译它(尽管您可能已经预编译头文件),链接器将解析(或不解析)臃肿的目标代码。
仅仅因为类定义很小并不意味着它应该在头文件中,除非定义也与声明相同 - 例如纯虚拟类或其他答案中提到的简单类型。