我从未真正理解为什么c++需要一个单独的头文件,其中包含与.cpp文件中相同的函数。它使得创建类和重构类变得非常困难,并且给项目添加了不必要的文件。还有一个必须包含头文件的问题,但是必须显式地检查它是否已经被包含。
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
后续问题:
当我所包含的是.h文件时,编译器如何找到其中的代码的.cpp文件?它是假定.cpp文件与.h文件具有相同的名称,还是实际上遍历目录树中的所有文件?
我从未真正理解为什么c++需要一个单独的头文件,其中包含与.cpp文件中相同的函数。它使得创建类和重构类变得非常困难,并且给项目添加了不必要的文件。还有一个必须包含头文件的问题,但是必须显式地检查它是否已经被包含。
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
后续问题:
当我所包含的是.h文件时,编译器如何找到其中的代码的.cpp文件?它是假定.cpp文件与.h文件具有相同的名称,还是实际上遍历目录树中的所有文件?
当前回答
c++在1998年被批准,那么为什么要这样设计呢?使用单独的头文件有什么好处?
实际上头文件在第一次检查程序时变得非常有用,检查头文件(仅使用文本编辑器)可以让您概述程序的体系结构,不像其他语言,您必须使用复杂的工具来查看类及其成员函数。
其他回答
c++的设计目的是在C基础设施中添加现代编程语言的特性,而无需不必要地更改C语言中与语言本身无关的任何内容。
是的,在这一点上(在第一个c++标准诞生10年之后,在它开始大量使用20年之后),很容易会问为什么它没有一个合适的模块系统。很明显,现在设计的任何新语言都不能像c++那样工作。但这不是c++的意义所在。
c++的重点是进化,是现有实践的平稳延续,只是添加新的功能,而不(经常)破坏对用户社区来说足够有效的东西。
这意味着,与其他语言相比,它使一些事情变得更困难(特别是对于开始一个新项目的人),而另一些事情则更容易(特别是对于维护现有代码的人)。
因此,与其期待c++变成c#(这毫无意义,因为我们已经有了c#),为什么不选择正确的工具来完成这项工作呢?就我自己而言,我努力用现代语言(我碰巧使用c#)编写大量的新功能,并且我有大量现有的c++,我将它们保存在c++中,因为重新编写它们将没有真正的价值。它们融合得很好,所以基本上是无痛的。
c++是这样做的,因为C是这样做的,所以真正的问题是为什么C要这样做?维基百科对此做了一些说明。
较新的编译语言(例如 Java、c#)不使用转发 声明;标识符 从源自动识别 文件和读取直接从动态 符号库。这意味着头文件 不需要文件。
我认为头文件背后的真正(历史)原因是使编译器开发人员更容易……但是,头文件确实有优势。 查看之前的帖子了解更多讨论…
第一个优点:如果没有头文件,就必须在其他源文件中包含源文件。这将导致在包含的文件更改时重新编译包含的文件。
第二个优点:它允许在不同的单元(不同的开发人员、团队、公司等)之间共享接口而无需共享代码。
有些人认为头文件是一种优势:
It is claimed that it enables/enforces/allows separation of interface and implementation -- but usually, this is not the case. Header files are full of implementation details (for example member variables of a class have to be specified in the header, even though they're not part of the public interface), and functions can, and often are, defined inline in the class declaration in the header, again destroying this separation. It is sometimes said to improve compile-time because each translation unit can be processed independently. And yet C++ is probably the slowest language in existence when it comes to compile-times. A part of the reason is the many many repeated inclusions of the same header. A large number of headers are included by multiple translation units, requiring them to be parsed multiple times.
归根结底,头文件系统是70年代C语言刚被设计出来时的产物。当时,计算机的内存非常少,将整个模块保存在内存中是不可能的。编译器必须从文件顶部开始读取,然后线性地遍历源代码。报头机制支持这一点。编译器不需要考虑其他翻译单元,它只需要从上到下读取代码。
c++为了向后兼容而保留了这个系统。
今天,这毫无意义。它效率低下,容易出错,而且过于复杂。如果目标是分离接口和实现,还有更好的方法。
然而,c++ 0x的建议之一是添加一个适当的模块系统,允许代码像。net或Java那样被编译成更大的模块,所有这些都是一次性的,而且没有头文件。这个提议在c++ 0x中没有被采纳,但我相信它仍然属于“我们希望以后再做这个”的范畴。也许在TR2或类似的地方。