我从未真正理解为什么c++需要一个单独的头文件,其中包含与.cpp文件中相同的函数。它使得创建类和重构类变得非常困难,并且给项目添加了不必要的文件。还有一个必须包含头文件的问题,但是必须显式地检查它是否已经被包含。
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
后续问题:
当我所包含的是.h文件时,编译器如何找到其中的代码的.cpp文件?它是假定.cpp文件与.h文件具有相同的名称,还是实际上遍历目录树中的所有文件?
我从未真正理解为什么c++需要一个单独的头文件,其中包含与.cpp文件中相同的函数。它使得创建类和重构类变得非常困难,并且给项目添加了不必要的文件。还有一个必须包含头文件的问题,但是必须显式地检查它是否已经被包含。
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
后续问题:
当我所包含的是.h文件时,编译器如何找到其中的代码的.cpp文件?它是假定.cpp文件与.h文件具有相同的名称,还是实际上遍历目录树中的所有文件?
当前回答
如果你想让编译器自动找到其他文件中定义的符号,你需要强迫程序员把这些文件放在预定义的位置(就像Java包的结构决定了项目的文件夹结构)。我更喜欢头文件。此外,你还需要你所使用的库的源代码,或者一些统一的方法来把编译器需要的信息放在二进制文件中。
其他回答
你可以在没有头文件的情况下完美地开发c++。事实上,一些大量使用模板的库并不使用头文件/代码文件范例(参见boost)。但是在C/ c++中,你不能使用没有声明的东西。一个实用的方法 处理这个问题的方法就是使用头文件。此外,您还可以在不共享代码/实现的情况下共享接口。我认为这不是C语言的创造者所能想象到的:当你使用共享头文件时,你必须使用著名的:
#ifndef MY_HEADER_SWEET_GUARDIAN
#define MY_HEADER_SWEET_GUARDIAN
// [...]
// my header
// [...]
#endif // MY_HEADER_SWEET_GUARDIAN
这并不是真正的语言特性,而是处理多重包含的一种实用方法。
所以,我认为在创建C时,前向声明的问题被低估了,现在当使用像c++这样的高级语言时,我们必须处理这类事情。
对于我们这些可怜的c++用户来说,这又是一个负担……
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
实际上头文件在第一次检查程序时变得非常有用,检查头文件(仅使用文本编辑器)可以让您概述程序的体系结构,不像其他语言,您必须使用复杂的工具来查看类及其成员函数。
c++是在1998年被批准的,但它的使用时间比那要长得多,而且批准主要是规定当前的用法,而不是强加结构。由于c++是基于C语言的,而C语言有头文件,所以c++也有头文件。
使用头文件的主要原因是支持文件的单独编译,并最小化依赖关系。
假设我有foo.cpp,我想使用bar.h/bar.cpp文件中的代码。
我可以在foo.cpp中#包含“bar.h”,然后编程和编译foo.cpp,即使bar.cpp不存在。头文件向编译器承诺bar.h中的类/函数将在运行时存在,并且它已经拥有了它需要知道的一切。
当然,如果bar.h中的函数没有body当我试图链接我的程序时,它就不会链接,我就会得到一个错误。
一个副作用是,您可以在不透露源代码的情况下为用户提供头文件。
另一种情况是,如果更改了*.cpp文件中代码的实现,但根本不更改头文件,则只需要编译*.cpp文件,而不需要编译使用它的所有内容。当然,如果您在头文件中放置了大量的实现,那么这就变得不那么有用了。
我认为头文件背后的真正(历史)原因是使编译器开发人员更容易……但是,头文件确实有优势。 查看之前的帖子了解更多讨论…
c++是这样做的,因为C是这样做的,所以真正的问题是为什么C要这样做?维基百科对此做了一些说明。
较新的编译语言(例如 Java、c#)不使用转发 声明;标识符 从源自动识别 文件和读取直接从动态 符号库。这意味着头文件 不需要文件。