上文简述了类模板相关功能,本文主要简述为什么模板不支持分离编译?

  在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++】模板简述(四):模板为什么不支持分离编译?的更多相关文章

  1. 【C++】模板简述(一):模板的引入

    我们在介绍模板之前,首先想象有这么一个场景: 我们需要通过C++写出一个通用的加法程序,那么有如下几种方法: 方法一:C++的函数重载 //int int int int Add(int l,int ...

  2. 【C++】模板简述(六):总结

    1.模板技术是泛型编程的基础.([C++]模板简述(一):模板的引入) 2.模板被编译两次,因而给分离编译造成一些麻烦.([C++]模板简述(二):函数模板.[C++]模板简述(四):模板为什么不支持 ...

  3. c++模板函数声明定义分离编译错误详解

    今天看到accelerated c++上有个简单的vector容器的实现Vec,就再vs2008上编译了下: ///// Vec.h #ifndef GUARD_VEC_H #define GUARD ...

  4. ZT 类模板的声明和实现是不能分离的

    http://bbs.csdn.net/topics/380250382 adlay adlay 等级: #9 得分:0 回复于: 2012-03-31 11:19:35 引用 6 楼  的回复: 引 ...

  5. 关于C++模板不能分离编译的问题思考

    C++模板不支持分离编译的思考 前言 在我初入程序员这行时,因为学生阶段只写一些简单的考试题,所以经常是将声明和实现统一写到一个文件中,导致同事在用我的代码时一脸懵逼,因此还有一段悲惨的往事. 为什么 ...

  6. 【C++】模板简述(三):类模板

    上文简述了C++模板中的函数模板的格式.实例.形参.重载.特化及参数推演,本文主要介绍类模板. 一.类模板格式 类模板也是C++中模板的一种,其格式如下: template<class 形参名1 ...

  7. C++ Primer 学习笔记_76_模板与泛型编程 --模板定义[续]

    模板与泛型编程 --模板定义[续] 四.模板类型形參 类型形參由keywordclass或 typename后接说明符构成.在模板形參表中,这两个keyword具有同样的含义,都指出后面所接的名字表示 ...

  8. 实现C++模板类头文件和实现文件分离的方法

    如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer(第四版)>>里的观点:1)标准C++为编译模板代码定义了两种模型:“包含”模型和“ ...

  9. C++ Primer 学习笔记_76_模板和泛型编程 --模板定义[继续]

    模板和泛型编程 --模板定义[续] 四.模板类型形參 类型形參由keywordclass或 typename后接说明符构成.在模板形參表中,这两个keyword具有同样的含义,都指出后面所接的名字表示 ...

随机推荐

  1. ps -ef | grep

    ps -ef | grep java   查看所有关于java的进程 root     17540     1  0  2009 ?        01:42:27 /usr/java/jdk1.5. ...

  2. 比特币客户端bitcoind的高级用法

    Bitcoin 比特币官方客户端有两个版本:一个是图形界面的版本,通常被称为 Bitcoin(首字母大写),以及一个简洁命令行的版本(称为 bitcoind).它们相互间是兼容的,有着同样的命令行参数 ...

  3. 主机与虚拟机互ping

    1.设置虚拟机网络连接方式(如下图): 2.设置主机和虚拟机的ip为同一个网段,如主机ip:192.168.28.1,虚拟机ip:192.168.28.128 3.如果相互还是ping不通,就检查一下 ...

  4. Java语法基础练习2

    ---恢复内容开始--- 1.仔细阅读示例:EnumTest.java分析结果 代码: 运行结果: 分析:枚举类型就是一个类,枚举中的常量就是枚举类型中的实例,可把字符串转化为枚举:而且他本身是一个类 ...

  5. poj中的一些线段树

    poj2828 链接:http://poj.org/problem?id=2828 题解: 初始状态 首先是插入3 69 1,4结点有4个位置, 1,2结点有2个位置,小于3,因此放到1,4结点右孩子 ...

  6. AppDomain加载与释放dll

    AppDomain加载与释放dll 几年前写过同名随笔,但今天应不大适用了.但还有几个朋友留言关注,我重新发布相关代码. 首先我们的目的就是运行期间更新dll,并应用dll.这个过程需要应用 AppD ...

  7. softmax regression in c++

    #include <iostream>#include <vector>#include <cmath>#include <algorithm>#inc ...

  8. ObjectInputStream与ObjectOutputStream类实现对象的存取

    1. ObjectInputStream与ObjectOutputStream类所读写的对象必须实现Serializable接口,对象中的transient和static类型成员变量不会被读取和写入 ...

  9. java笔记之IO3读操作

    * 字节输入流操作步骤: * A:创建字节输入流对象 * B:调用read()方法读取数据,并把数据显示在控制台 * C:释放资源 *  * 读取数据的方式: * A:int read():一次读取一 ...

  10. 如何替换某文件中的所有的特定字符?---linux sed命令(文本编辑命令) (转载)

    转自:http://blog.csdn.net/year_9/article/details/20318407 sed是一个很好的文件处理工具,主要是以行为单位进行处理,可以将数据行进行替换.删除.新 ...