为什么需要前向声明? [英] Why are forward declarations necessary?

查看:32
本文介绍了为什么需要前向声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
C++ 应该消除头文件吗?

在 C# 和 Java 等语言中,无需在使用之前声明(例如)类.如果我理解正确,这是因为编译器对代码进行了两次传递.第一个它只是收集可用的信息",第二个它检查代码是否正确.

In languages like C# and Java there is no need to declare (for example) a class before using it. If I understand it correctly this is because the compiler does two passes on the code. In the first it just "collects the information available" and in the second one it checks that the code is correct.

在 C 和 C++ 中,编译器只执行一次传递,因此此时所有内容都需要可用.

In C and C++ the compiler does only one pass so everything needs to be available at that time.

所以我的问题基本上是为什么在 C 和 C++ 中不这样做.是不是就不需要头文件了?

So my question basically is why isn't it done this way in C and C++. Wouldn't it eliminate the needs for header files?

推荐答案

简而言之,从定义 C 到 25 年后 Java 出现之间,计算能力和资源呈指数级增长.

The short answer is that computing power and resources advanced exponentially between the time that C was defined and the time that Java came along 25 years later.

更长的答案...

编译单元的最大尺寸——编译器在单个块中处理的代码块——将受到编译计算机的内存量的限制.为了处理您键入机器代码的符号,编译器需要将所有符号保存在一个查找表中,并在代码中遇到它们时引用它们.

The maximum size of a compilation unit -- the block of code that a compiler processes in a single chunk -- is going to be limited by the amount of memory that the compiling computer has. In order to process the symbols that you type into machine code, the compiler needs to hold all the symbols in a lookup table and reference them as it comes across them in your code.

当 C 语言于 1972 年创建时,计算资源更加稀缺且价格昂贵 - 一次存储复杂程序的整个符号表所需的内存在大多数系统中根本不可用.固定存储也很昂贵,而且速度极慢,因此像虚拟内存或将部分符号表存储在磁盘上这样的想法根本不允许在合理的时间范围内进行编译.

When C was created in 1972, computing resources were much more scarce and at a high premium -- the memory required to store a complex program's entire symbolic table at once simply wasn't available in most systems. Fixed storage was also expensive, and extremely slow, so ideas like virtual memory or storing parts of the symbolic table on disk simply wouldn't have allowed compilation in a reasonable timeframe.

该问题的最佳解决方案是通过让人工提前在哪些编译单元中对符号表的哪些部分进行分类,将代码分成更小的部分.向程序员强加一个相当小的任务来声明他使用什么,从而节省了让计算机在整个程序中搜索程序员可以使用的任何东西的巨大努力.

The best solution to the problem was to chunk the code into smaller pieces by having a human sort out which portions of the symbol table would be needed in which compilation units ahead of time. Imposing a fairly small task on the programmer of declaring what he would use saved the tremendous effort of having the computer search the entire program for anything the programmer could use.

它还使编译器不必对每个源文件进行两次传递:第一次对其中的所有符号进行索引,第二次对引用进行解析并查找它们.当您处理磁带时,查找时间以秒为单位,读取吞吐量以每秒字节数(不是千字节或兆字节)为单位,这非常有意义.

It also saved the compiler from having to make two passes on every source file: the first one to index all the symbols inside, and the second to parse the references and look them up. When you're dealing with magnetic tape where seek times were measured in seconds and read throughput was measured in bytes per second (not kilobytes or megabytes), that was pretty meaningful.

C++ 是在将近 17 年后创建的,它被定义为 C 的超集,因此必须使用相同的机制.

C++, while created almost 17 years later, was defined as a superset of C, and therefore had to use the same mechanism.

到 1995 年 Java 出现时,普通计算机已经拥有足够的内存来保存符号表,即使对于一个复杂的项目,也不再是一个沉重的负担.而且 Java 的设计初衷并不是为了向后兼容 C,所以它不需要采用遗留机制.C# 也同样不受阻碍.

By the time Java rolled around in 1995, average computers had enough memory that holding a symbolic table, even for a complex project, was no longer a substantial burden. And Java wasn't designed to be backwards-compatible with C, so it had no need to adopt a legacy mechanism. C# was similarly unencumbered.

因此,他们的设计者选择将划分符号声明的负担从程序员身上转移到计算机上,因为它的成本与编译的总工作量成正比.

As a result, their designers chose to shift the burden of compartmentalizing symbolic declaration back off the programmer and put it on the computer again, since its cost in proportion to the total effort of compilation was minimal.

这篇关于为什么需要前向声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆