.cpp文件和.h文件有什么区别?

时间:2009-05-17 20:54:48

标签: c++ header include

因为我已经制作了.cpp文件然后将它们转换成.h文件,我唯一能找到的区别就是你不能#include .cpp文件。我有什么不同之处吗?

8 个答案:

答案 0 :(得分:50)

C ++构建系统(编译器)没有区别,所以它都是约定。

约定是.h文件是声明,.cpp文件是定义。

这就是为什么.h文件是#included - 我们包括声明。

答案 1 :(得分:22)

.cpp文件是编译单元:它是将编译的真实源代码文件(用C ++编写)。

.h(标题)文件是将在#clude预编译器指令出现的.cpp文件中虚拟复制/粘贴的文件。一旦将头文件代码插入.cpp代码中,就可以开始编译.cpp了。

答案 2 :(得分:12)

  

我知道声明和定义之间的区别。

鉴于:

  • CPP文件包含其包含的任何标题中的定义(因为CPP和标题文件一起成为单个“翻译单元”)
  • 头文件可能包含多个CPP文件
  • 链接器通常不喜欢在多个CPP文件中定义的任何内容

因此,头文件中的任何定义都应该是内联的或静态的。头文件还包含由多个CPP文件使用的声明。

既不是静态也不是内联的定义都放在CPP文件中。此外,在一个CPP文件中只需要的任何声明通常都放在该CPP文件本身中,而不是任何(可共享的)头文件中。

答案 3 :(得分:7)

.h文件或头文件用于列出类声明中可公开访问的实例变量和方法。 .cpp文件或实现文件用于实际实现这些方法并使用这些实例变量。

它们分开的原因是因为.hpp文件不会编译成二进制代码.h文件。以图书馆为例。假设您是作者,并且您不希望它是开源的。因此,您将已编译的二进制库和头文件分发给您的客户。这使他们可以轻松地查看有关您的库可以使用的类的所有信息,而无法看到您如何实现这些方法。它们更适合使用代码而不是编译器的人。如前所述:这是惯例。

答案 4 :(得分:6)

标题(.h.hpp,...)文件包含

  • 班级定义(class X { ... };
  • 内联函数定义(inline int get_cpus() { ... }
  • 功能声明(void help();
  • 对象声明(extern int debug_enabled;

源文件(.c.cpp.cxx)包含

  • 功能定义(void help() { ... }void X::f() { ... }
  • 对象定义(int debug_enabled = 1;

但是,实际上并不需要使用.h后缀命名标头和使用.cpp后缀命名的源文件的约定。人们总是可以告诉一个好的编译器如何处理某个文件,而不管它的文件名后缀是什么(-x <file-type>对于gcc。像-x c++)。

源文件将包含在整个程序中只能出现一次的定义。因此,如果您在某处包含源文件,然后将该文件的编译结果与源文件本身之一链接在一起,那么您当然会遇到链接器错误,因为您现在会将这些定义出现两次:一次进入包含源文件,然后在包含它的文件中。这就是你在包含.cpp文件时遇到问题的原因。

答案 5 :(得分:1)

其他人已经提供了很好的解释,但我认为我应该澄清各种扩展之间的差异:

  Source Files for C: .c
  Header Files for C: .h

  Source Files for C++: .cpp
  Header Files for C++: .hpp

当然,正如已经指出的那样,这些只是惯例。编译器实际上并没有关注它们 - 它纯粹是为了编码器的利益。

答案 6 :(得分:1)

一个好的经验法则是“.h文件应该有多个源文件[可能]使用的声明,但没有运行的代码。”

答案 7 :(得分:0)

按照惯例,.h文件包含在其他文件中,并且永远不会直接编译。 .cpp文件 - 按照惯例 - 再次是编译过程的根源;它们直接或间接包含.h文件,但通常不包括.cpp文件。