引用C++primer的话:C++支持两种模板编译模式包含模式(Inclusion   Model )和分离模式(Separation Model)

1. 包含编译模式

在包含编译模式下,在每个模板被实例化的文件中包含函数模板的定义并且往往把定义放在头文件中像对内联函数所做的那样。

2. 分离编译模式

在分离编译模式下函数模板的声明被放在头文件中 ,  在模板定义中有一个关键字export,  关键字export   告诉编译器在生成被其他文件使用的函数模板实例时可能需要这个模板定义编译器必须保证在生成这些实例时该模板定义是可见的 , 关键字export   不需要出现在头文件的模板声明中, 分离模式使我们能够很好地将函数模板的接口同其实现分开进而组织好程序以便把函数模板的接口放到头文件中而把实现放在文本文件中, 但是并不是所有的编译器都支持分离模式, 即使支持也未必总能支持得很好, 支持分离模式需要更复杂的程序设计环境所以它们不能在所有C++编译器实现中提供。

3. 详细说明

大部分编译器在编译模板时都使用包含模式,也就是一般使用时把模板放到头文件中在包含。当你不使用这个模版函数或模版类,编译器并不实例化它 ,当你使用时,编译器需要实例化它,因为编译器是一次只能处理一个编译单元, 也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义 ,所以都放在头文件中。这不同于普通的函数, 在使用普通的函数时,编译时只需看到该函数的声明即可编译, 而在链接时由链接器来确定该函数的实体。

4.举例说明

//test.h
template<class T>
class Test()
{
public:mFun();
private:T value;
}____________________________
//test.cpp
#include"test.h"void Test<T>::mFun()
{...
}_____________________________
//main.cpp
#include"test.h"int main()
{Test<int> m_test;m_test.mFun();//#1return 0;
}

编译器在#1处并不知道Test<int>::mFun的定义,因为它不在test.h里面,于是编译器只好寄希望于连接器,希望它能够在其他.obj里面找到Test<int>::mFun的实例,在本例中就是test.obj,然而,后者中真有Test<int>::mFun的二进制代码吗?NO!!!因为C++标准明确表示,当一个模板不被用到的时侯它就不该被实例化出来,test.cpp中用到了Test<int>::mFun了吗?没有!!所以实际上test.cpp编译出来的test.obj文件中关于Test::mFun一行二进制代码也没有,于是连接器就傻眼了,只好给出一个连接错误。但是,如果在test.cpp中写一个函数,其中调用Test<int>::mFun,则编译器会将其实例化出来,因为在这个点上(test.cpp中),编译器知道模板的定义,所以能够实例化,于是,test.obj的符号导出表中就有了Test<int>::mFun这个符号的地址,于是连接器就能够完成任务。

为什么C++模板函数的声明与实现都放在.h文件中相关推荐

  1. 为什么模板函数的声明和实现都放在.h文件中

    当你不使用这个模板函数或模板类,编译器并不实例化它,当你使用时,编译器需要实例化它,因为编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义.所以都放在 ...

  2. 【C++】模板函数的声明和定义必须在同一个文件中

    1.问题描述 习惯性的将函数的定义和实现,分别写在头文件和源文件(.cpp)中.今天也按照这个习惯实现了一个模板函数.然后编译时报错 ... error: undefined reference to ...

  3. c++模板函数的声明和定义该在什么文件里?

    最近在写模板函数的时候,发现了一个问题. 按照江湖规矩我们的声明一般放在.h文件,定义放在.cpp文件. 而在写模板函数的时候,套用江湖规矩会出错. 解决方法:将模板函数的声明和定义都放在.h文件中. ...

  4. 为什么C++模板声明与定义要放在同一文件中?

    写了3年多C++程序,很少用到模板,我靠,今天想试一下,照着别人的例子写,什么鬼,怎么都运行不过,仔细比对代码才发现,C++模板的声明与定义必须放到一个文件,.h或者.hpp, 真是颠覆我对C++编程 ...

  5. C++模板函数的声明和定义是否可以分开?

    如果按照普通函数一样,将模板函数的声明与定义的分开,声明放在头文件,定义放在cpp文件实现,你会发现,编译没问题,但是在链接阶段会报"undefined references". ...

  6. error LNK2005 --类的声明和定义放在一个文件中

    刷C++primer的时候,将类的声明和定义均放在头文件中,报错error LNK2005 1> Sales_data.h 1>Sales_data.obj : error LNK2005 ...

  7. 将函数实现放在头文件中

    研究一个开源算法库,采用C++模板编程,所有函数实现都放在了头文件中,现在把模板去掉,链接时发生冲突,具体原因如下: 因为多个源文件包含了含有函数定义的头文件,在编译的时候,每个源文件都会包含一份函数 ...

  8. 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中

    将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...

  9. 利用fputc函数写一个putw(w,fp)函数,将整数w写入fp所指文件中; 利用fgetc函数写一函数getw(fp)从所指文件读出一整数

    <程序设计基础-c语言>杨莉 刘鸿翔 ISBN-978-7-03-032903-5 p257 习题8 5.利用fputc函数写一个putw(w,fp)函数,将整数w写入fp所指文件中: 利 ...

最新文章

  1. 003_Maven插件
  2. django 不用自带的mysql_python笔记二 django自带后台管理系统、模版渲染以及使用mysql数据库...
  3. SQL查询系列之六:SQL模糊查询
  4. 200+猫在线待撸!来pick你最爱的那只!
  5. when is OData model initialized - finally found done by Framework
  6. Android开发之View双指缩放ViewGroup双指缩放视频双指缩放图片双指缩放
  7. 基于JAVA+SpringMVC+Mybatis+MYSQL的学生公寓管理系统
  8. Huffman编码树
  9. 简述RHEL7新特性(二)
  10. vvv在线文档导出工具_墙裂推荐 | 在线文档编辑工具
  11. 数据挖掘导论阅读笔记第一章:绪论
  12. win下安装nessus
  13. 用c语言写一个求和的程序,用C语言编写一个“等比数列求和”的程序?
  14. Android简历模板
  15. GBase 8c 安全特性
  16. 五星级洒店系统需求分析
  17. 龙芯3A4000处理器解读①
  18. 思域第三方app安装方法(提权)
  19. GSoC: GitHub Checks API 项目第一阶段总结
  20. 【数据分析】指标体系

热门文章

  1. AutoSAR操作系统以及概念
  2. access sql 取余_SQL 教程
  3. Jenkins出现一个错误 无法连接到Jenkins如何解决
  4. js将json自动转html表格实例
  5. 【Linux】Linux编程之 mmap解析
  6. 【算法题目】有n个台阶,青蛙一次只能跳1步到k步,请问有多少种跳法?
  7. python 论坛爬虫代码_python博客文章爬虫实现代码
  8. zabbix监控物理网卡流量
  9. echarts+vue+koa+websocket(精)
  10. 搜索引擎 梁斌的那本走进搜索引擎很不错,简明扼要