如果x.h只包含一个函数声明,为什么需要在 x.cpp 中包含x.h?或者你永远不能这样做吗?
// x.h
void f();
// x.cpp
void f() { }
x.cpp 中没有任何内容取决于 x.h 的内容。你不需要#include "x.h"
.
// x.h
void f()
// x.cpp
int f() { return 0; }
在这里,x.cpp中的定义与x.h冲突。如果 x.cpp 在顶部#include "x.h"
,编译器会看到这一点,并给你一条错误消息。
// x.h
struct x { };
// x.cpp
x f() { x my_x; return my_x; }
在这里,x.cpp 中的代码需要标头中x
的定义。代码需要#include "x.h"
才能编译。(是的,您可以在不使用#include
指令的情况下在 x.cpp 中重复struct x
的定义,如果 x.cpp 中struct x
的定义是正确的;使用标头可确保定义相同,而不必保持定义的多个副本同步(。
总之:如果不需要,则不必包含标头。但总的来说,这是一个好主意,因为它可能会导致编译器捕获错误,迟早可能需要它。当我实现新的东西时,我创建头文件,然后编写 x.cpp 的第一个版本:
// x.cpp
#include "x.h"
编译此源文件将捕获 x.h 中的语法错误。
来自C++ Microsoft文档:
为了尽量减少出错的可能性,C++采用了该约定 使用头文件包含声明。你使 头文件中的声明,#include 然后在 需要该声明的每个.cpp文件或其他头文件。#include 指令将头文件的副本直接插入到 编译前的.cpp文件。
但是,您也可以将所有声明放在源文件中,而不是使用头文件,因为(但是这样您将有很多重复的代码,即函数声明(:
编译程序时,每个.cpp文件都是独立编译的 变成编译单元。编译器不知道什么名称 在其他编译单元中声明。这意味着如果你定义 类或函数或全局变量,必须提供声明 在使用它的每个附加.cpp文件中的那个东西。
因此,您永远不能有头文件,但您需要将函数声明放在使用该函数的每个源文件中。如果您有多个函数声明,这将导致大量重复的代码。因此,强烈建议使用头文件。
您不必使用头文件,但强烈建议这样做。
您可以手动复制所有声明,尽管存在缺点,但复制和粘贴从未真正过时。
此外,您不必在实现文件中包含相应的头文件(第一个(,大多数声明应该在定义中重复。
不这样做会删除一个重要的健全性检查,这有助于发现致命的不一致。
即使没有这个一切正常,编译器验证声明和定义是否匹配也很有用。