头文件的使用
来源:2-2 使用模板(泛型)编写算法
阿阳2017
2023-01-27
老师你好,这节课中,在头文件中直接实现自定义结构体的相关代码,对这种方式感觉到好奇。我已经参考了您的另外一个回答:
https://coding.imooc.com/learn/questiondetail/RAKpB2PJ8xWXbv0E.html
但是还有一个疑问就是:这个.h文件,在编译的时候也和.cpp文件一样编译么?课程中大致的理解是:“在Student.h中,把声明和实现一起写了出来,相当于一个开源项目,因为.h是不对外隐藏的;.cpp文件经过编译后,对外界隐藏。”,好奇是,这个h文件也被编译成可执行文件了么?那.h和.cpp好像除了信息隐藏,也没啥其他区别了。
2回答
-
.h文件是头文件,内含函数声明、宏定义、结构体定义等内容
.c文件是程序文件,内含函数实现,变量定义等内容。而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的文件采取某些动作。你可以强制编译器把任何后缀的文件都当作c文件来编。
这样分开写成两个文件是一个良好的编程风格。10 -
liuyubobobo
2023-01-31
“这个.h文件,在编译的时候也和.cpp文件一样编译么?”
这其实是一个很“基础”的 C++ 问题,但是我很理解很多经常使用 C++ 的程序员都不很理解 C++的编译机制(其实包括其他语言的编译机制),尤其是国内很多教育相对忽视这一点。
简单回答就是,h 文件是不参与编译的,h 文件参与的是预处理。所以 #include 这类以 # 开头的指令叫做预处理指令。C++ 中的预处理指令可以参考这里:https://cplusplus.com/doc/tutorial/preprocessor/
#include 是最典型的预处理指令,预处理器处理 #include 的方式也非常简单,就是直接把 #include 对应的文件(通常是 .h 文件)的所有内容,直接复制粘贴到 cpp 文件中。最终编译器只针对 cpp 文件做编译工作。(compile)
==========
h 和 cpp 分离,除了对外界做隐藏之外,从软件工程的角度,更重要的是信息的分离,即接口和具体实现做分离。所以你可以不用知道 vector 是怎么实现的,只要 #include <vector>,然后直接用 vector 就好了。
你说的“开源“,是我选择将具体逻辑程序放到 h 中的最不重要的原因,而最重要的原因是,C++ 的模板类“原生”不支持这种信息分离(实践一下试试看?我在你引用的问答里也给出了一个关于这个问题的讨论链接。)
从业界的角度,把具体实现放在 h 中也并不是不常用的手段。随便放一个例子。比如微软的 C++ STL 的开源实现,其整个 vector 类就是完整是现在 vector 的头文件中的:https://github.com/microsoft/STL/blob/main/stl/inc/vector
这背后还有一个重要的原因,把类实现放在 h 文件中,是一种隐式的声明内联(inline)的方式。深入下去涉及太多 C++ 的内容了。有兴趣你可以查询学习一下诸如这种问题的讨论:https://stackoverflow.com/questions/14517546/how-can-a-c-header-file-include-implementation
(但如果你是以 C++ 作为主语言,尤其是工作用的话,还是建议完整学习 C++ 的知识。C++ 的知识非常庞大,说实话,是远高于“面试常用算法”这个范畴的。这里的 C++ 书单可以参考:https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list )
继续加油!:)
112023-02-04
相似问题