Forward declaration与Include Header Files的区别及适用场景是什么?
前向声明(Forward declaration)与头文件引入(Include Header Files)的核心区别
- 本质不同:前向声明只是告诉编译器「某个类型/函数是存在的」,不会引入对应的实现和完整定义,比如C++里的
class User;就是典型的前向声明;引入头文件是直接把对应头文件的全部内容插入到当前编译单元,会导入目标的完整定义、依赖、宏等所有内容,比如#include "user.h"就是典型的头文件引入操作。 - 编译性能影响不同:前向声明不会增加编译单元的体积,也不会触发链式头文件引入,能大幅减少编译耗时;引入头文件如果嵌套过多,会导致编译单元膨胀,大幅拖慢全量/增量编译速度。
- 依赖耦合度不同:前向声明不会引入编译依赖,修改被声明的目标的内部实现时,当前编译单元不需要重新编译;引入头文件会建立强编译依赖,只要头文件内容有变动,所有引用它的编译单元都要重新编译。
- 使用限制不同:前向声明的类型属于「不完整类型」,你只能用它声明指针、引用,或者作为函数的返回值/参数类型,不能直接创建实例、访问内部成员;引入头文件后拿到的是完整类型,没有使用限制。
实际开发的使用场景
优先用前向声明的场景
只要满足以下条件,就优先用前向声明:
- 你只需要在当前头文件里声明该类型的指针、引用
- 你只需要把该类型作为函数声明的参数、返回值,不需要在头文件里写函数实现
举个常见场景:你写的类里有一个User*成员指针,只需要在头文件顶部加class User;即可,不需要引入user.h。
必须引入头文件的场景
出现以下任意一种情况,你就必须引入对应头文件:
- 你需要创建该类型的实例,或者要继承这个类型
- 你需要访问该类型的成员变量、成员函数、内部类型/枚举
- 你需要知道该类型的内存大小(比如用
sizeof计算,或者把它作为成员变量放在你的类里而不是指针/引用) - 你用到的是模板类型、宏定义,只能通过头文件引入
额外注意:不要在头文件里引入不必要的头文件,尽量把头文件引入放到
.cpp实现文件里,能显著降低项目的编译依赖,减少编译时间,也能避免头文件循环引入的问题。
内容的提问来源于stack exchange,提问作者Ahmed gamal seliman
相关产品推荐
相关产品推荐

