我是一个适度的有经验的Java / C#程序员,我最近开始学习C ++。问题是,我无法理解如何构建各种头和代码文件。这似乎主要是由于我缺乏了解,以编译器如何连接一切融合在一起。我试着读一些教科书,但我的预想,被我Java和C#的知识严重着色。例如,我有一个很难在着手与方法等可以在一个命名空间,而不是只在一个类定义来定义的事实。

我已经找到了很多C ++的 - >的Java / C#教程,但几乎没什么走另一条路。是否有良好的资源,在那里为缓解在Java / C# - > C ++过渡,特别是对于理解编译过程

有帮助吗?

解决方案

C ++ FAQ 是关于所有的特质的优秀资源C ++,但它可能是一个更先进一点比你要找的 - 大部分的问题(不只是答案)是神秘甚至相当有经验的C ++开发人员

我想,如果你谷歌的C ++教程,你就可以找到的东西。你也可以尝试学习汇编语言(或者至少得到一个简要介绍,以东西实际上是如何在微处理器发生),C和C ++都非常接近他们做事方式的硬件。这是他们的速度和力量从何而来,但它是在一些漂亮的抽象Java提供的价格。

我可以尝试回答您的具体问题上面问过,但我不知道我有多好会做。

一个关键理解头文件和cpp文件之间的关系的是理解为“转换单元”的概念。 Java类文件可以被认为是翻译单元,因为它是被编译成二进制形式的基本单位。在C ++中,几乎每一个CPP文件是一个翻译单元(也有例外,如果你正在做怪异的东西)。

一个头文件可以被包括在多个翻译单元(和必须包括到处使用任何在头中定义)。 #include指令真的只是做一个文本替换 - 包含文件的内容逐字插入其中#include指令。通常要在头文件中定义类的接口,并在cpp文件的执行情况。这是因为你不想成为暴露你的实施细则,其他翻译单元可以包含头。在C ++中,一切,包括类,是不是真的有钱的对象,只是内存块,编译器通过编译相同的头信息到每个翻译单元分配的含义......,编译器保证所有的翻译单元有什么样的内存块代表相同的理解。因为缺乏编译时间后丰富的数据的,像反射是不可能的。

在C ++生成过程被连接,这是在链接器将所有已编译的翻译单元和查找符号第二步(通常函数调用,而且变量)在翻译单元中使用,但没有定义。然后,它会寻找另一个翻译单元,其定义了符号和“链接”在一起,以使得特定功能的所有呼叫被定向到翻译单元定义它。

在类方法的情况下,必须将它们通过一个类的实例,其是在幕后只是一个指向一块内存调用。当编译器看到这些类型的方法调用时,它输出调用一个函数,隐式地传递指针,被称为this指针,到功能作为第一个参数的代码。你可以有不属于类功能(不是方法,如你所说,因为一个方法是正确类的成员函数,因此没有一个类可以不存在),因为连接基不具有类的概念。这将看到,调用一个函数的平移单元,其定义了一个函数,另外,领带在一起。

这结束了更长的比我预想的好多了,当然是一个过于简单化,但它是正确的,以我的知识和提供的细节水平的...希望它可以帮助一些。至少它应该给你一些谷歌上搜索的起点。

其他提示

这是一些困惑我,当我用C,以及第一次开始。书籍不做说明正确使用页眉与代码文件的一个好工作。

在编译器通过加载每个.cpp文件和编译它独立于所有其他人。在编译的第一步是加载所有由#include语句中提到的标头的。你可以把它做整个foo.h中只要有一个的#include的文本插入“foo.h中”。

什么是如何构建的文件这意味着什么?头文件应该有任何需要的程序部分用于其他.cpp文件引用。作为一般规则,实现不应该在头文件。这会导致问题。头文件应包括类,函数和全局变量的声明(如果必须使用它们)。

我真的建议从约C ++编译器解释避而远之,看着在C编译器的解释。根据我的经验,这些都是解释的更好,避免与OOP的问题混淆你。查找有关C分离汇编材料。我就不得不提到你从我的母校一个伟大的幻灯片小册子,但它不是英文。

C语言编译和Java / C#之间的主要区别是,编译不创建解决实体。换句话说,当你在Java的编译,编译器会查找任何引用的类已编译的类文件,并确保一切可用和一致。基本假设是,当你最终运行程序时,这些文件也将是可用的。

一个编译的C文件,另一方面,仅仅是一个“承诺”。它依靠的依赖关系是什么样子(在函数声明的形式)的声明,但也有这些定义在任何地方任何保证。你需要做的最困难的心态开关是认为C文件的不仅仅是该文件,而是作为该文件与它包括一切聚合(即,什么预处理器生成)。换句话说,编译器不看的头文件,好像一个大文件。编译器保留一切“至今下落不明”的生成目标文件中的轨道。后来,在链接时,链接器,使办结这个试图填补所有空白与从不同的目标文件材料。

你可能想知道为什么编译和链接是分开的,以及(因为我没有看到解释它的任何职位,这是一个很大的混乱,不知道的事情的根本原因的原因)。

链接和编译完成seperately,因为(和可能有不止一个原因)的需要做库调用。如果定义或任何之流,实施这些报头中的函数原型的代码是已编译并坐在某个地方作为目标代码libary的一部分。如果一个巨大的编译过程将被代替,你需要有编译期间这些库调用源,以及更多的时间,因为你会还编译库代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top