【问题标题】:Why does C/C++ have header files unlike other languages like C# and Java? [duplicate]为什么 C/C++ 与 C# 和 Java 等其他语言不同,有头文件? [复制]
【发布时间】:2013-06-19 23:54:53
【问题描述】:

我对动机很感兴趣 - C/C++ 中通过头文件将接口与实现分离的动机是什么以及为什么其他语言的作者不借用这个概念并将其用于其他(较新) 语言? 是不是说明这个概念不好?

编辑:我不是在问为什么 c/c++ 使用头文件 - 我是在问为什么这个概念没有保留在 Java 等较新的语言中。

【问题讨论】:

  • 那么,在 70 年代和 80 年代设计语言时,您如何建议 C“从新语言中借用概念”? ;)
  • C# 和 Java 使用编译后的代码来实现与 C/C++ 中的头文件相同的功能。他们只是这样做,而不会将一堆定义复制到一个单独的文件中。
  • @Petesh 是的,为什么他们不复制?
  • @Novellizator 因为他们不必这样做,而且这些语言的设计者有丰富的 C/C++ 经验,并且知道界面的另一个副本只是如果你已经有一个,那就不好了。
  • @Novellizator 为什么语言会选择使用头文件?他们这样做会得到什么?

标签: c# java c++ c


【解决方案1】:

在设计 C 语言时,计算机的资源非常少,因此将处理时间和内存使用量保持在最低限度非常重要。使编译器能够读取源文件并在single pass 中以最少的资源使用“即时”编译它的设计优于使编译器在源代码上执行multiple passes 或在发出编译代码之前在内存中构造一个大型数据结构。头文件支持一次性编译:它们为您提供了declare 的方法并使用符号,而它的定义 可能会出现在源代码的后面,或者它甚至可能在不同的文件中或外部库。

C# 和 Java 等较新语言的设计认为程序员的便利性比优化编译器的资源使用更重要。此外,许多现代 C 编译器已经使用多次传递,因为不可能在一次传递中应用许多代码优化;如今,对新语言使用单通道设计几乎没有什么好处。

头文件还有其他好处:它们允许您将接口与实现分开,这样头文件就可以用作 API 文档,而不会暴露实现细节。

【讨论】:

  • 有趣的是,您说 C 是一次性语言。许多 C 定义需要 2 遍。 Pascal(以及 Ada,因为它是一个后代)可以一次读取(尽管 Ada 95 有一个例外。)
  • C 中需要两次编译器传递的部分是否范围有限?
  • C 和 C++ 之间存在差异,但在 C 中,例如,您可以定义一个没有返回类型的函数。 int 用作默认值。您可能会在 C 中收到警告,但它是合法的(C++ 假设这样但会产生错误。)如果您查看解析器,为了实现这一壮举,它必须做一些非凡的事情,我认为这非常复杂,而且每个功能都会发生。此外,当您到达句法结构(通常是 } 或 ;)的末尾时,您需要确定刚刚定义的内容,因为在解析下一个条目时可能需要它。
  • 现在......在 C++ 中,您可以按照您想要的顺序在类中声明函数。这使它变得更加复杂,并且肯定会迫使您阅读课程,但并不是真正的块(类中 { 和 } 之间的任何内容都只是“存储”)一旦读取了整个课程,然后您就开始处理这些块,包括子类、子结构等。否则你不知道如何处理你在函数中找到的标识符。
【解决方案2】:

我不确定这是否适合 Stackoverflow,但是:

当我编写课程时,我很欣赏拥有单独的 .h 和 .cpp 文件的清晰性。这对我有几个好处:

1:当其他人必须使用我的类时,他们只需要读取 .h 文件 - 类的方法内部没有代码可以混淆他们 - 这个函数的调用类似于 so,这是解释它的作用的评论,你不需要知道其余的。

2:当我必须检查我的代码时,拥有单独的 .h 和 .cpp 可以让我进行比较/对比。如果我在 .cpp 中有一个我最终不需要的半生不熟的方法,那么两个文件之间就会不匹配。因此,我可以使用更清晰的 .h 文件,该文件更易于查看,以查看我是否设法在 .cpp 文件中做错了。

【讨论】:

  • 你错了。 .h 文件包含类包含的每个私有成员变量。它通过名称和签名向您显示所有私有成员函数,即使它们的主体不存在。它没有将接口与实现分开。有一种将接口与实现分离的机制很好,有时,在好的一天,.h/.cpp 分离可能有点看起来像它实现了这一点。但它不是真的,不干净。其他语言有,但 C++ 没有。所以面对现实吧,这不是“欣赏”的东西,对你没有好处。
  • 这是一种笨拙的 hack,起源于 70 年代设计 C 语言时,因为当时计算机速度太慢,内存太少,无法在编译时处理更复杂的事情。如果这些语言是在今天设计的,它们就会适当地将接口与实现分开。但他们没有。
  • 我是说 .h 文件不包含所有私有成员变量吗?编辑:等等,我可以看到我写的内容可能会让你这么想。我会更准确地编辑我的答案。
  • 您说没有“类内部”的代码来迷惑 .h 文件的读者。这就是它应该的样子,这就是它在现代、精心设计的语言中的样子。但是 C++ 不存在,假装它存在是不诚实的。现在,我们被 .h/.cpp 分隔所困,所以嘿,让我们充分利用它。但是,让我们不要假装它可以让我们分离实现和接口,或者类似的东西。它不仅包含类的所有私有成员,还包含所有内联函数和模板函数——现代 C++ 代码中有很多。
  • 在第二部分,你也错了,因为如果存在不匹配,编译器很少检测到。您可以在头文件中声明函数而不在 .cpp 文件中定义它们,这对编译器来说很好。或者您可以在.cpp 中定义一个函数,而无需在.h 中声明,编译器对此也没有任何问题。它不会强制两个文件之间的一致性,因此它会使您的审阅工作更难,而不是更容易。
猜你喜欢
  • 2012-01-05
  • 2015-06-04
  • 2017-07-31
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多