首页 > 模板的分离编译

模板的分离编译

模板不支持分离编译
我们来分析一下模板为什么不支持分离编译呢,所谓的分离编译就是我们在编写程序的时候可能会出现如下的一种情况就是,(我下面就是举具体的例子了)
代码
//*****************template.h***********//
#include
using namespace std;template
class A
{
public:void Show();
private:T a;
};//*****************template.cpp***********//
#include"template.h"template
void A::Show()
{T m;cout << "hello" << endl;
}//*****************test.cpp***********//
#define _CRT_SECURE_NO_WARNINGS 1
#include"template.h"int  main()
{A a;a.Show();return 0;
}
现象一
上面的程序中,我们调用的时候会出现如下的报错
1>test.obj : error LNK2019: 无法解析的外部符号 "public: void __thiscall A::Show(void)" (?Show@?$A@H@@QAEXXZ),该符号在函数 _main 中被引用
1>W:CodeC++TemptlateSeparateCompilationDebugTemptlateSeparateCompilation.exe : fatal error LNK1120: 1 个无法解析的外部命令
现象二
我们改一下代码再来看一个现象,如果我们在主函数中把a.Show给注释掉,然后在template.cpp把cout<<"hello"<
在进行编译的时候,发现竟然没有报错,这就奇怪了吧
从预处理,编译,汇编,链接的角度来分析问题
我们知道模板的一个特性,只有当调用的时候才会实例化它,而我们的程序从一开始的文本到最后的可执行程序经历了四个过程,分别是预处理,编译,汇编,链接,最后是在链接的时候出现了错误
一.预处理
在预处理的时候,会进行头文件展开,这个时候会把头文件中的函数声明展开到test.cpp和template.cpp中
二.编译
在编译test.cpp时由于只能看到模板声明而看不到实现,因此不会实例化模板函数,但此时不会报错,因为编译器认为模板定义在其它文件中,就把问题留给链接程序处理。
在编译template.cpp的时候,编译的时候会进行一些检查,比如一些语法的检查,然后生成汇编代码,因为我们的模板函数是在调用的时候才会进行实例化,即只有在调用模板函数的时候才会生成代码,但是在我们的编译的时候,在template.cpp这个文件中是没有对函数进行实例化,所以并没有生成汇编的代码,这也是上面的第二种情况为什么我们的代码错误从却没有被检查出来的原因,因为我们的根本就没有生成汇编代码
三.汇编
再来接着分析,在汇编的时候就是生成二进制代码,然后是一个.obj文件,在linux下面是.o文件,同时生成一个符号表,符号表中放置的就是我们所有函数的地址。
四.链接.
当我们进行最后一步链接的时候,执行到a.Show();会去.ob文件中查找我们的函数地址,这里有一个符号表,但是因为我们没有生成一个函数代码,所以这个函数表是查找不到的,所以这个时候就会报上面的错误。
还需要分析的一个问题就是,为什么我们把函数的声明和定义放置在一个文件中的时候就可以呢,因为如果我们把函数声明和定义放置在一个头文件中的话,我们在编译的时候,就会头文件展开了,这个时候调用了我们的函数,然后又是在一个文件内如就会直接直接生成代码,然后在查找的时候就会很容易的查找到这个内容。
解决办法
方法一:
使用上面说的内容,放模板函数的声明和定义放在一个头文件下面
但是这样会出现一些问题
(1)放置在头文件中,暴露了模板函数的 内容
(2)不符合分离编译的原则
方法二
我们可以在函数声明的时候加上一个export,就是下面的这种形式
export void Show();
但是很多的编译器是不支持的
方法三
我们可以显示的实例化,就是我们可以在头文件中对我们需要的内容 进行一个显式的实例化

更多相关:

  • 英语的重要性,毋庸置疑!尤其对广大职场人士,掌握英语意味着就多了一项竞争的技能。那,对于我们成人来说,时间是最宝贵的。如何短时间内在英语方面有所突破,这是我们最关心的事情。英语学习,到底有没有捷径可以走,是否可以速成?周老师在这里明确告诉大家,英语学习,没有绝对的捷径走,但是可以少走弯路。十多年的教学经验告诉我们,成功的学习方法可以借...

  • 展开全部 其实IDLE提供了一个显32313133353236313431303231363533e78988e69d8331333365663438示所有行和所有字符的功能。 我们打开IDLE shell或者IDLE编辑器,可以看到左下角有个Ln和Col,事实上,Ln是当前光标所在行,Col是当前光标所在列。 我们如果想得到文件代码...

  • 前言[1]从 Main 方法说起[2]走进 Tomcat 内部[3]总结[4]《Java 2019 超神之路》《Dubbo 实现原理与源码解析 —— 精品合集》《Spring 实现原理与源码解析 —— 精品合集》《MyBatis 实现原理与源码解析 —— 精品合集》《Spring MVC 实现原理与源码解析 —— 精品合集》《Spri...

  • 【本文摘要】【注】本文所述内容为学习Yjango《学习观》相关视频之后的总结,观点归Yjango所有,本文仅作为学习之用。阅读本节,会让你对英语这类运动类知识的学习豁然开朗,你会知道英语学习方面,我们的症结所在。学习英语这类运动类知识,需要把握四个原则第一,不要用主动意识。第二,关注于端对端第三,输入输出符合实际情况第四,通过多个例子...

  • 点云PCL免费知识星球,点云论文速读。文章:RGB-D SLAM with Structural Regularities作者:Yanyan Li , Raza Yunus , Nikolas Brasch , Nassir Navab and Federico Tombari编译:点云PCL代码:https://github.co...

  • 《初级前端开发人员经常容易忽视几个细节问题汇总》 1、使用 变量.toString()的时候记得对变量进行判空 2、使用 字符串.indexOf()的时候记得对字符串变量进行判断是否为null或undefined 3、使用 数组.length 或 数组[1]、数组[2] 的时候记得对数组进行判断是否为null或undefined...

  • 使用ET模型的时候,一定要注意,每次收到有效通知,然后读取数据的时候,务必每次读取干净(读到出错为止)。当再次调用check(sockfd)的时候才能正确返回。...

  • 有时候看到有意思的demo,在头痛导入项目的编码和workspace的编码不一样的时候 我试着将 笔记本打开一个类一个类的复制, demo的类比较少的时候 可以忍受,demo的类多的时候 除了靠之外 别无办法 今天再找仿ios样式demo的时候 实在受不了乱码,新浪一搜,出现给力的工具类 大致思路 挺简单的 无非是找到路径 重新转码。...

  • 90后的无奈:当我们出生的时候,奶粉里都有毒了,当我们长身体的时候,只能吃垃圾食品了,当我们要上幼儿园的时候,开始乱收费了,当我们大学毕业的时候,毕业就是失业了,当我想努力赚钱的时候股市倒了,当我想努力谈恋爱的时候帅哥都成GAY了,当我想追求一切流行的时候,又开始非主流了!80后的无奈:当我们读小学的时候,读大学不要钱;我们要读大学...

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...