• 【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

  • 相关阅读:
    步步为营——算法初阶 1.算法概述
    Spring学习【Spring概述】
    Codeforces 490F Treeland Tour 树上的最长上升子序列
    汽车电商竞争白热化,“五大门派”谁能登顶?
    程序猿的出路
    Android Studio Share Project On Github
    hdu 1022 Train Problem I(栈的应用+STL)
    Scala, Groovy, Clojure, Jython, JRuby and Java ----我们的工作语言
    Oracle GoldenGate (ogg) 11.2.1.0.20 是最后一个支持oracle db 10g的 ogg版本号
    javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
  • 原文地址:https://www.cnblogs.com/qq329914874/p/6729324.html
Copyright © 2020-2023  润新知