【C++】模板简述(四):模板为什么不支持分离编译?
上文简述了类模板相关功能,本文主要简述为什么模板不支持分离编译?
在C++中,为了一个项目的规范,我们通常把代码归为三类:声明文件、实现文件、测试文件.
比如,我要用C++实现一个链表,那么就会创建这3个文件:
LinkList.h //链表的相关声明
LinkList.cpp //链表的实现代码
Test.cpp //链表测试代码(本文忽略)
那么问题来了,普通链表这样写起来一点问题都没有!
如果一旦,我要通过类模板来实现链表(仍然用以上文件结构),编译器就会报错:无法解析的外部符号.....
那么为什么呢???
我们先来简单的分析一下,编译器报的这种错误属于链接性错误,也就是当程序预处理、编译、汇编、链接,在链接时出现了错误.
而一般出现链接错误,通常是因为,声明了一个函数,但是没有写实现体.
因此,当程序在链接时,从符号表中只找到了函数名,找不到具体函数实现的地址,因此编译器会报出这样的错误!
那么问题又来了:为什么当模板在分离编译时会报出这样的错误呢?
我简述一下,我们知道模板需要两次编译(第二篇文章提到过):
第一次编译是在实例化之前:用来分析基本的语法错误,
第二次编译是在实例化之后,当把这个类型替换之后,判断有没有语法错误.
重点就是在这里!!!!!!!!
我们模板代码的实现体在一个文件里,
而实例化模板的测试代码在另一个文件里,
编译器编译一个文件时并不知道另一个文件的存在,
因此,模板代码就没有进行实例化,编译器自然不会为其生成代码,因此会抛出一个链接错误!
解决方法:
1.在模板头文件xxx.h中进行显示实例化,在模板类定义后面直接添加template class SeqList<int>;(不推荐,老版编译器可能不支持!)
2.将定义与声明放到一个文件xxx.hpp里.(推荐此方法)
因为,本系列文章都是简述,因此在这里我向大家推荐一个讲解的比较详细博客:http://blog.csdn.net/pongba/article/details/19130
【C++】模板简述(四):模板为什么不支持分离编译?的更多相关文章
- 【C++】模板简述(一):模板的引入
我们在介绍模板之前,首先想象有这么一个场景: 我们需要通过C++写出一个通用的加法程序,那么有如下几种方法: 方法一:C++的函数重载 //int int int int Add(int l,int ...
- 【C++】模板简述(六):总结
1.模板技术是泛型编程的基础.([C++]模板简述(一):模板的引入) 2.模板被编译两次,因而给分离编译造成一些麻烦.([C++]模板简述(二):函数模板.[C++]模板简述(四):模板为什么不支持 ...
- c++模板函数声明定义分离编译错误详解
今天看到accelerated c++上有个简单的vector容器的实现Vec,就再vs2008上编译了下: ///// Vec.h #ifndef GUARD_VEC_H #define GUARD ...
- ZT 类模板的声明和实现是不能分离的
http://bbs.csdn.net/topics/380250382 adlay adlay 等级: #9 得分:0 回复于: 2012-03-31 11:19:35 引用 6 楼 的回复: 引 ...
- 关于C++模板不能分离编译的问题思考
C++模板不支持分离编译的思考 前言 在我初入程序员这行时,因为学生阶段只写一些简单的考试题,所以经常是将声明和实现统一写到一个文件中,导致同事在用我的代码时一脸懵逼,因此还有一段悲惨的往事. 为什么 ...
- 【C++】模板简述(三):类模板
上文简述了C++模板中的函数模板的格式.实例.形参.重载.特化及参数推演,本文主要介绍类模板. 一.类模板格式 类模板也是C++中模板的一种,其格式如下: template<class 形参名1 ...
- C++ Primer 学习笔记_76_模板与泛型编程 --模板定义[续]
模板与泛型编程 --模板定义[续] 四.模板类型形參 类型形參由keywordclass或 typename后接说明符构成.在模板形參表中,这两个keyword具有同样的含义,都指出后面所接的名字表示 ...
- 实现C++模板类头文件和实现文件分离的方法
如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer(第四版)>>里的观点:1)标准C++为编译模板代码定义了两种模型:“包含”模型和“ ...
- C++ Primer 学习笔记_76_模板和泛型编程 --模板定义[继续]
模板和泛型编程 --模板定义[续] 四.模板类型形參 类型形參由keywordclass或 typename后接说明符构成.在模板形參表中,这两个keyword具有同样的含义,都指出后面所接的名字表示 ...
随机推荐
- Statement 与 PreparedStatement 区别
Statement由方法createStatement()创建,该对象用于发送简单的SQL语句 PreparedStatement由方法prepareStatement()创建,该对象用于发送带有一个 ...
- 基于TINY4412的Andorid开发-------简单的LED灯控制【转】
本文转载自:http://www.cnblogs.com/pengdonglin137/p/3857724.html 基于TINY4412的Andorid开发-------简单的LED灯控制 阅读 ...
- JavaScript 图片广告自动与手动的切换
1.代码 <html> <head> <script type="text/javascript" src="jquery-1.8.j ...
- JSTL1.1函数标签库(functions)如fn:length
JSTL1.1函数标签库(functions)如fn:length 分类: java ssh22012-06-11 09:02 313人阅读 评论(1) 收藏 举报 stringcharacterxm ...
- HDU - 4513 吉哥系列故事――完美队形II(manacher)
1.找出一个最长的回文子串,要求中间的值最大,然后向两侧递减. 2.判断条件改为:Ma[i+Mp[i]]==Ma[i-Mp[i]]&&Ma[i-Mp[i]]<=Ma[i-Mp[i ...
- bzoj4326
二分+树剖+差分 之前的做法naive,莫名其妙的wa,明明uoj95分 看到最小最大上二分,树上路径问题直接剖,然后问题就转化成了一个判定问题,每次二分出最长路径长度,问能不能达到.那么我们就把所有 ...
- UI:用UITableView制作通讯录的关键代码
分析{功能分析(打电话.添加联系人.修改联系人),模块分析(联系人展示.详情模块.添加模块)} 拿到一个项目,首先分析项目框架(工程框架) 首先:判断是否是用户第一次安装:(如果是的,那就加载用户引导 ...
- ChartCtrl源码剖析之——CChartTitle类
CChartTitle类顾名思义,该类用来绘制波形控件的标题,它处于该控件的区域,如下图所示: CChartTitle类的头文件. #if !defined(AFX_CHARTTITLE_H__499 ...
- wincap的安装与环境配置
首先开始知道什么是wincap? 1 通常情况下,大多数的网络应用程序都是通过操作系统来访问网络(sockets),这样是算比较简单的了,毕竟已经封装好了 ,有的时候呢需要一些底层的细节比如协议处理, ...
- ThinkPHP3.2.3学习笔记4---统计ThinkPHP3.2.3加载的文件
将ThinkPHP3.2.3的入口文件index.php加入一个函数getIncludeFiles,文件内容变成如下所示: <?php // +------------------------- ...