c++编译链接过程与原理
我们创建lesson2工程,包括main.cpp stdafx.cpp Fish.cpp Animal.cpp以及对应的.h头文件,其中main.cpp是程序入口点,如图1所示。
图1 工程文件
他们的源码如下:
Animal.h
//#ifndef endif防止头文件重复包含 #ifndef _ANIMAL_H_ #define _ANIMAL_H_ class Animal { public: Animal(); virtual void eat(); virtual void sleep(); virtual void breath(); }; #endif
Animal.cpp
#include "stdafx.h" #include "Animal.h" //为了让编译器识别Animal #include <iostream> //为了识别cout using namespace std; //Animal.cpp 是编译单元,所以需要#include相关头文件 Animal::Animal() { } void Animal::breath() { cout << "Animal breath." << endl; } void Animal::eat() { cout << "Animal eat." << endl; } void Animal::sleep() { cout << "Animal sleep" <<endl; }
Fish.h
//#ifndef endif防止头文件重复包含 #ifndef _FISH_H_ #define _FISH_H_ #include "Animal.h"//为了让编译器识别Animal是个类 class Fish : public Animal { public: Fish(); virtual void breath(); virtual void eat(); virtual void sleep(); }; #endif
Fish.cpp
#include "stdafx.h" #include "Fish.h" //为了让编译器识别Fish #include <iostream> //该文件调用了cout c++标准库需要 using namespace std; //Fish.cpp 是编译单元 是编译单元,所以需要#include相关头文件 Fish::Fish() { } void Fish::breath() { cout << "Fish breath" << endl; } void Fish::eat() { cout << "Fish eat" << endl; } void Fish::sleep() { cout << "Fish sleep" << endl; }
main.cpp
// main.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "Animal.h" #include "Fish.h" int _tmain(int argc, _TCHAR* argv[]) { Animal animal; animal.breath(); animal.eat(); animal.sleep(); Fish fish; fish.breath(); fish.eat(); fish.sleep(); return 0; }
完成编码后,使用快捷键"Cltr + Alt +F7",会输出包含如下的信息,如图2所示。
如图2 编译信息
从上图,我们可以看到可执行程序lesson2.exe的产生,大致经过了两个步骤:
编译:
第一步C++编译器对工程中的三个源文件Fish.cpp、Animal.cpp main.cpp单独进行编译(Compiling…)。在编译时,先由预处理器对预处理指令(#include、#define和#if)进行处理,在内存中输出翻译单元(一种临时文件)。编译器接受预处理的输出,将源代码转换成包含机器语言指令的三个目标文件(扩展名为obj的文件):main.obj、Fsh.obj、Animal.obj。
注意,在编译过程中,头文件不参与编译;在lesson2工程的Debug目录下,我们可以看到编译生成的obj文件。
链接:
第二步是链接过程(Linking…),链接器将目标文件和你所用到的C++类库文件一起链接生成lesson2.exe。整个编译链接的过程如图3所示。
图3 编译和链接过程
输出结果如下: