在一切之前,我们需要首先了解C++的编译过程
C++的编译过程分大致为预编译、编译、链接。
在预编译过程中,会进行一些最基本的操作。
#define Max 100
如程序中出现了上面的语句,则预编译结束后,程序中的所有 Max 都已经被替换成了100
#ifndef XXX
#define XXX
#endif
其实上面的语句相当与一个常用的if判断语句,只不过这个判断语句实在在预编译阶段完成对的
//main.cpp文件内容
#include "my.h"
void main()
{
}
//my.h文件内容,有一个变量声明和一个函数声明
int age;
void show(void);
//预编译后
int age;
void show(void);
void main()
{
}
可以分为两个过程,编译和汇编
编译过程将会检查程序中的语法错误,若没有错误则会将程序转换成汇编语言
汇编过程会将汇编语言的程序转换成机器语言。
注意:此过程涉及分文件编写过程。
C++编译的一个特点就是 分文件编译 ,也就是每一个.cpp文件都会单独进行编译。
也就是说每一个.cpp文件都会单独生成一个目标文件。
但是这样就出现了一个问题:
如果一个木目标文件中的函数调用了另一个目标中的函数怎么办呢??
一个项目,假设预编译之前是这样子的:
经过预编译之后会变成下图的样子:
链接过程就是将各个文件最重链接成一个可执行.exe文件的过程。
首先需要合并文件,将各个".obj"文件合并为一个文件,然后找到编译阶段生成的 特殊符号 的实现。最终生成一个可执行文件。
首先模板就是模板,不是数据类型。
硬要是说模板像点什么的话,我感觉它更像是函数。
就这样吧,我自己的理解,不知对错。
首先我们需要知道几个知识:
编译过程:
由于在同一个文件中,在编译阶段,编译器首先会找到类模板的声明(用于检查语法错误)。
然后会找到模板的定义。最后找到类模板的使用,会将其实例化。很简单的过程。
首先,我们一般会重写模板类的构造方法,用来进行一些操作(属性赋初值等),所以以下为重写构造方法的情况。
经过预编译程序会由
首先,在临时文件1中,有类模板的声明和定义,语法上无错误,但是没办法创建成员函数,也没有具体的模板参数列表,所以类模板中的成员函数此时并没有创建。
然后,在临时文件2中,虽然有类模板的声明,也有函数调用(构造函数),按道理,在这个时候应该创建并调用成员函数。但是因为该文件中没有函数定义(函数定义在临时文件1中),所以无法创建成员函数,也就无法调用。
可是,这并不会报错,因为,编译器认为,成员函数的定义在其他文件中,编译器会把该工作交给链接器来完成,编译器则会使用一个特殊符号来代替这个函数。
接下来是链接阶段,问题就出现了。
由于临时文件2中使用到了一个该文件中不存在的函数,所以链接器会在其他文件中来寻找该函数的定义。但是在临时文件1中,虽然有函数的定义,但是并没有类模板的参数列表,没有参数列表类模板的成员函数是无法创建的,所以在临时文件1中链接器也没有这个函数。所以就会出现未定义符号的错误。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务