1)预处理器: 将#include"" #define 等预编译命令后的语句在文件中展开,为了防止循环include某个文件,一般采用#pragma once 或者#ifndef #define #endif等方法。预处理过的代 码一般放在一个中间文件中。此时你的工程中有N个
中间文件。2)编译器: 每个中间文件都以一个编译单元,并且可以单独编译,但是每个编译单元中的变量编译器一定要知道。要实现这个功能就要靠变量(或者函数)的声明。声明是告诉编译器,我有 这样一个类型的变量,或者这个类型的函数,等会要用到,你等会检查的时候,看看我传入的参数和返回值是不是符合原型,符合的话你就不要报错了。如果编译期间进行了语法检查之 后没有错误的话,编译器会将这种中间文件生成
目标模块.obj格式文件。这种文件中一般是汇编语言。
3)连接器: 把一组目标模块连接成一个可执行程序。这个时候就需要变量或者函数的定义了。如果A目标模块中有个函数void f(int a){};B模块中需要调用f(1)的话,连接器会去搜索 库,如果A模块在这个库中的话,那么A模块就会被连接进这个B模块,但是整个库不会被连接进来,不然,exe文件就太大了。
4)声明与定义 声明不分配空间。
定义分配空间。
有时声明一个变量与定义一个变量混在一起。如果想分开,就用extern,明确表明这是一个声明,该变量的定义在该文件后面或者在另一个文件里面。函数声明一般是默认
e xtern的。
5)连接阶段的外连和内连 控制一个变量或者一个函数的可见性。extern 外连。static 内连。 const?忘了。
6)头文件 一般放变量或者函数的声明,可以被包含。C++中有多次包含,一次定义的规定,所以,变量的定义一般不放在头文件中,防止多次定义。
7)连接器如何查找库 当C++要对函数或者变量进行外部引用的时候,根据引用情况,有两种处理方法。一、如果还没有遇到过这个变量或者函数的定义,连接器把它的标志符加到“未解析的引用”列表 中;二、如果连接器遇到过定义,那就加到“解析的引用“列表中。
如果在当前目标模块找不到定义,它将会去查找库。在库中找到定义后,就将整个模块而不仅仅是函数定义连接到可执行程序。(其实我要的只是这么一个函数,一个模块太多 了)。
因为连接器按照指定的顺序查找文件(先查本模块,再查库文件),所以,如果你预先定义了一个库中的同名函数的话,那么就不会调用库中的方法了。
这就是为什么如果你重载了 new和delete之后,标准的new delete就不再有用的原因了。所以大家要重载这两个操作符的时候一般不要弄成全局函数,一般要弄成成员函数哈。8)名字空间 防止名字冲突,加一层保护。
posted on 2012-05-28 15:00
Dino-Tech 阅读(368)
评论(0) 编辑 收藏 引用