为什么C++需要通过标头或语句进行前向声明,而 Java 不需要?
why does a C++ need a forward declaration either through a header or a statement and Java doesn't need?
如果你不转发声明你的函数,Java不会抱怨,而C++会抱怨。我知道C++涉及预处理,但我想了解更多。
对象文件
Java 编译器依赖于编译到它们生成的字节码 (.class) 文件中且您的代码使用的额外信息,而C++编译器不会将此类信息存储在它们生成的编译对象代码 (.obj) 文件中。
作为一种较旧的语言,C++依赖于程序编译和链接的"C模型"。这意味着对象文件主要包含代码和数据,只有足够的元数据即可将目标文件链接在一起(在运行时静态或动态)。因此,编译器依赖于解析源代码时包含的头文件来了解代码引用的外部类类型、函数和变量。
这也意味着C++代码的客户端需要代码的目标文件(.obj、.lib 或 .dll)和头文件才能自行使用它。
Java 是一种更现代的语言,它将大量符号元数据存储到它生成的对象 (.class) 文件中,这允许编译器在以后的编译中提取代码引用的外部类类型、方法和变量。
这也意味着 Java 代码的客户端只需要代码的目标文件(.class 或 .jar)即可使用它。
前瞻声明
Java编译器对源代码进行多次传递,这意味着你只需要在代码中的一个位置声明/定义一个变量或方法;前向声明不是必需的,因为编译器更努力地确定类型信息。
相比之下,C++被定义为
Java使用.class
文件格式。编译器收集有关类的信息并将其放入.class
文件中。在结果中,可以在不涉及源文件的情况下完成链接。请注意,在 Java 中,每个文件都有一个公共类需求,因此为每个源文件生成一个.java
.class
。
在C++代码通常被编译为object
文件,这些文件不知道类或结构等高级概念。因此,必须在头文件中提供信息,以便编译器可以在进入链接阶段之前执行检查(甚至知道如何生成一些代码)。
我一直在寻找前向声明背后的基本原理,但是 K&R 的 ANSI C(它可能是从 C 继承的"功能")只是声明每个变量必须在使用前声明,并且 ANSI C 对与定义一致的函数进行了前向声明(它们之前不需要兼容)。
因为 c++ 没有导出模块定义的概念。如果要公开函数或类,以便其他.cpp(模块)可以访问它,则必须在.h文件中转发声明它们。为什么不在 .h 中编写整个函数(定义)和类,而不是前向声明它们并写在 .cpp 文件中? 因为当你 #include 它几乎包含了整个.h文件的内容.cpp所以如果你把它包含在你拥有的所有.cpp文件中,它将在每个.cpp中重复编译。这可能效率极低。因此,您只需要 .h 中的前向声明和.cpp中的所有定义。
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 为什么output_editor Concept不需要output_e迭代器标记
- 为什么转换函数声明不需要至少一个定义类型说明符
- 如果在C++中不需要构造函数或析构函数,是否有必要显式声明它?
- C++不正确,不需要重新声明类成员变量 MFC 手工解决方案/项目 MS VS 2015
- 为什么 c++ lambda 捕获不需要类型声明?
- C++,为什么结构/类中不需要前向声明
- C++中的函数声明后不需要分号(';')吗?
- 下面链接中的声明不需要存储类说明符"static"。我说的对吗?
- 为什么C++需要通过标头或语句进行前向声明,而 Java 不需要?
- 朋友类概念不需要声明
- 模板类和处理不需要的类型声明的良好实践
- 需要帮助无法弄清楚为什么我的头文件函数声明不起作用
- 为什么在通过模板的静态调度中不需要前向声明
- 创建多个对象而不需要多个声明
- 使用函子的返回类型来声明模板方法的返回类型,不需要decltype
- C++ getline() 不需要命名空间声明
- c++调用约定是否受标准约束,因为在声明fn时不需要定义函数的返回类型
- 为什么C++不需要班级成员的前向声明?