在头文件中包含#include语句是一种很好的编程习惯吗?我个人觉得,尤其是当你经历一个别人写的代码库时,你最终会错过或花时间寻找可能在c文件中找到的定义。
答案 0 :(得分:3)
在某些情况下(根据我的经验 - 大多数),你不可能做你说的话。您经常最终会从代码中返回各种其他类,并且 - 显然 - 您需要在函数声明中包含有关该类的信息。在这种情况下,compiller必须已经知道那些其他对象是什么,所以你要么必须在声明中包含一个标题,要么提供一个前向声明。
因为无论如何你最终会包含标题,所以进行额外的前向声明并没有真正的意义。这当然是一种选择,但在我看来它并没有使你的代码更清晰。
此外 - 大多数IDE都可以选择在包含的文件中查找符号。
如果(并且只有,如果),您只需要定义中的类/函数,那么您可以投票将标题包含在*.c
文件中。乍一看可能很清楚,但您可能会发现 - 有一天在修改课程时 - 您最终会将#include
移动到*.h
文件。
答案 1 :(得分:2)
简短的回答是肯定的。如果一个特定的头定义/声明由在其他头文件中定义/声明的类,类型,结构等组成的类,类型,结构等,那么最方便有效的做法是包含那些头文件到头文件中。
通过这样做,依赖于您正在创建的头文件的头文件将存在。
可能存在多次包含文件的问题,这就是大多数头文件包含#if以确保文件仅包含一次或使用#pragma之类的内容以确保仅包含一次的原因。
总而言之,您应该设计头文件,以便多次使用头文件的#include多次包含头文件,头文件只会在预处理器输出中出现一次。通过在头文件中包含头文件所依赖的头文件,可以本地化头文件的使用,并确保所有依赖项都可用。
此外,通过在头文件中使用#include依赖头文件,如果包含路径不正确以使依赖头文件不可用,则很容易找到依赖于不可用的头文件头文件。
答案 2 :(得分:2)
头文件应该管理自己的依赖项;必须在.c文件中获得#include
的顺序只是才是浪费下午的烦人方式,这将是一个永久性的维护问题。如果您有任何需要的标题#include
,请在自己的标题中使用#include
警卫,并且 更容易生活。
答案 3 :(得分:1)
如果必须使头文件自包含,并且它不依赖于手动包含的任何其他头,那么它的风格并不坏。例如,如果标头包含使用stdint.h
中的数据类型的声明,那么它应该具有#include <stdint.h>
,而不是希望每个人都按照正确的顺序单独包含它。
同时,不管#include
或.h
是什么,不必要的.c
一般情况都不好。可以说是一个例外,可能是整个库的集合,理论上可以单独使用但是可以作为一个整体使用,例如一个完整的GUI工具包 - 在这种情况下,我认为有一些主标题拉动更清晰在所有声明中,而不是让用户了解哪个标题是哪个特定函数所必需的。
答案 4 :(得分:0)
我更喜欢在头文件中没有#include
,如果只是为了使每个源文件在一个地方可见。但这肯定是有争议的。
黄金法则是可读性。银色规则遵循现有做法。
答案 5 :(得分:0)
#include
任何你不需要的东西。不要#include
任何你不需要的东西,因为包含不必要的文件会导致不必要的依赖,并导致更大的项目的编译时间更长。因此,如果您修改现有的类以将vector
替换为list
,请花几秒钟查看文件并确保没有剩余任何vector
个残余结束,并从文件顶部删除#include <vector>
。
#include
。尽可能使用前向声明,因为它可以减少依赖性并最大限度地缩短编译时间。如果您的类标题没有声明该类的对象,则前向声明将会执行;如果您只通过引用或(在C ++中)通过引用使用它,那么您可以使用前向声明。
#ifdef
或#pragma
防护来设计您的头文件,使其不会多次包含。// MyClass.h
#ifndef MYCLASS_HEADER
#define MYCLASS_HEADER
// [header declaration]
#endif // MYCLASS_HEADER
或者在支持编译器上,例如Visual Studio:
// MyClass.h
#pragma once
// [header declaration]
这些警卫将允许您根据需要经常#include "MyClass.h"
,而不必担心在同一个翻译单元中多次包含它。
如果标题需要前向声明或完全包含标题,那么这样做是明智的。
如果标头没有用于标头 - 因为前向声明就足够了,或者因为只有.c / .cpp文件需要它 - 所以在标题中不要#include
。请记住:将所有内容推送到.c / .cpp文件中以减少依赖性并最大限度地缩短编译时间。