C++ 为什么编写模板类时要把方法的实现写在头文件中,而不能像写普通类一样写在源文件中?

2023-05-16

1、回答标题的问题

这里说下我自己的理解,如有不正确请各位大佬斧正。想要解决这个问题需要先了解C++代码的编译过程。

C++将代码编译生成可执行文件的过程可以分为三步:预编译 → 编译 → 链接。预编译时,会展开头文件,将包含的头文件的代码整个复制到当前文件中来。编译过程是生成二进制机器指令的过程。C++采用分离式编译,即,在编译时,对预编译源文件生成的文件(obj文件)进行单独编译,和其他文件没有任何关系。这时就有一个问题,当编译一个文件时,遇到了函数func,当前文件中只有预编译时拉进来的func的声明,而没有定义,无法生成func的二进制机器指令。这个问题,链接阶段会专门解决。在编译阶段,这些函数会暂时被标记为 “未解析的外部符号”。当进入链接阶段时, 链接器会专门为所有的未解析符号在其他文件中寻找对应的二进制机器指令,整个工程都链接好,就能正常执行了。

以上说的都是普通C++代码的编译过程。但是模板并不普通。模板只有在真正被使用到的时候才实例化,才生成二进制机器指令。当模板类的定义和实现分别写在了头文件和源文件中,而且main.cpp中还包含了模板类的头文件。那么编译main.cpp的obj文件时,势必会遇到模板类成员方法的声明,但是这里没有定义,先标记为未解析的外部符号。到了链接时,根据未解析的外部符号去到模板类源文件的obj文件中寻找其实现,找不到,因为他还没有被实例化,链接失败。此时,如果模板类成员方法的实现也在头文件中,那么就可以解决问题。

2、如何实现定义和实现分开写也能编译

非要把定义和实现分开写在头文件和源文件的话也不是不行。需要在源文件中添加模板类的实例化。

这个方法还是有局限性,因为你不知道类的使用方会套用什么类型,你需要对每个类型在cpp文件中挨个实例化一次,这就很麻烦,尤其是使用方套用的类型是自己定义了一个类的话,还是会出现链接错误。

写这篇文章参考了很多其他文章,下面一一列出。
C++程序是如何编译的?

C++ 编译,运行过程 详解。

C++类模板是如何编译的?

C++中模板类的编译过程
C++模板编译

C++模板为什么定义和实现必须都写在头文件?

模板为什么必须定义在头文件
关于C++为什么模板类中的模板函数只能写在头文件

C++模板类如何实现头文件和源文件分离?

C++模板类/函数,将头文件与源文件分离

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 为什么编写模板类时要把方法的实现写在头文件中,而不能像写普通类一样写在源文件中? 的相关文章

  • 导航卫星的时间系统

    1 GPS时间系统 xff08 GPST xff09 GPS系统是测时测距系统 时间在 GPS测量中是一个基本的观测量 卫星的信号 xff0c 卫星的运动 xff0c 卫星的坐标都与时间密切相关 对时间的要求既要稳定又要连续 为此 xff0
  • JT808协议介绍 --- 格林恩德 CR202 RTK 高精度车载定位器协议解读

    部标808又称为JT808 xff0c JT808标准的全称是 道路运输车辆卫星定位系统终端通讯协议及数据格式 808协议适用于GPS定位车载终端和监控平台之间的通信 当前市面上 xff0c 普通车辆监测设备所安装的GPS定位器 xff0c
  • C++析构函数调用顺序

    文章目录 析构函数工作过程 1 执行析构函数的函数体 2 如果该类中拥有类对象成员 xff0c 且类对象有析构函数 xff0c 则以类对象成员声明次序的相反顺序调用其析构函数 xff0c 销毁类对象成员 3 按原来构造顺序的相反顶序向上依次
  • TCP通信C++实现小例子

    TCP通信C 43 43 实现案例 https www bilibili com video BV1Dt411p74c t 61 1746 61 61 全部来自以上视频 xff0c 纯属搬运 xff0c 小可爱有问题可以举手提问哈 61 6
  • 串行通信简介

    一 串行通信与并行通信 计算机与外界的数据交换称为通信 xff0c 通信分为并行通信和串行通信两种基本方式 并行通信 串行通信 并行通信 xff1a 并行通信指各个数据位同时进行传送的数据通信方式 xff0c 因此有多少个数据位 xff0c
  • 使用寄存器点亮一个LED灯 普中科技stm32(stm32f1103zeb6)

    板子 xff1a 普中科技stm32F1 芯片stm32f1103zet6 1 程序如下 xff1a include 34 stm32f10x h 34 导入头文件 typedef unsigned int u32 typedef是系统关键
  • day 5 select服务器和客户端

    select客户端代码 xff1a include lt stdio h gt include lt string h gt include lt sys socket h gt include lt netinet in h gt inc
  • python Requests添加Auth和Cert

    最近通过postman发起另外一个项目的请求 xff0c 鉴权较为复杂 xff0c 首先需要设置cert xff0c postman中设置如下 xff1a 需要设置basic auth的参数 然后将接口返回的token放入auth的bear
  • STM32笔记(三)---寄存器映射--BSRR分析

    STM32笔记 xff08 三 xff09 寄存器映射 BSRR分析 GPIO与引脚区别 GPIO包含在引脚内 xff08 引脚内还有电源 晶振等特殊功能引脚 xff09 xff0c 除GPIO拓展内容即为单片机最小系统 GPIO功能如何检
  • ROS赵虚左6.5 Rviz中控制机器人模型运动_选了odom坐标系后小车变白不能动

    原因 xff1a 配置文件中的参考坐标不应该是base footprint xff0c 而是你自己小车最下面那个 小脚 的坐标系 xff0c 我的是footprint 所以把参考坐标换一下就可以了
  • 超声波传感器的基础

    超声波传感器已经有几十年的历史了 xff0c 但是由于它们的性能 灵活性和低成本 xff0c 它们仍然占据着传感市场的很大一部分 随着越来越多的产品实现了自动化 xff0c 随着机器人 自动驾驶汽车和无人驾驶飞机的出现 xff0c 需求进一
  • pthread_create未定义的引用

    在ubuntu使用gcc编译时出现 pthread create未定义的引用 问题 解决如下 xff1a 在编译时加入 l pthread 例如gcc thread c o thr l pthread 原因 xff1a pthread不是l
  • Linux下vscode实现调试

    1 安装好vscode xff0c 安装对应的插件 2 编写代码 xff0c 点击右上角的三角形 xff0c 生成对应可执行文件 3 点击菜单栏中的终端 配置任务 xff0c 选择 c c 43 43 xff1a GCC build act
  • 二进制数与十进制之间的转换以及使用一个函数实现任意进制之间的转换

    其他进制转为十进制都可以实现 xff0c 只需要将函数中的10和2换掉你需要的就行 include lt stdio h gt include lt math h gt 1 二进制转换为十进制 int twoConvertTen long
  • vscode配置C语言编译调试的方法

    一 安装GCC 官方下载 如果你能从在线安装 xff0c 那最好就在线安装吧 不过在线安装太容易中断失败了 如果你能连上官网 xff0c 也可以选择从官网去下载离线安装包 https sourceforge net projects min
  • C语言之补漏(1)

    typedef 1 define与typedef区别 xff1f 相比起宏定义的直接替换 xff0c typedef是对类型的封装 xff08 通俗说就是对类型起一个别名 xff09 2 typedef可以给多个别名 typedef int
  • 关于学习如何组装基于F4V3S飞控的竞速穿越机

    广西 河池学院 广西高校重点实验室培训基地 系统控制与信息处理重点实验室 本篇博客来自河池学院 智控无人机小组 创作时间2020 8 22 组装一架穿越机 xff0c 你需要的一些最基本的 xff0c 能让它飞起来的配件有 xff1a 机架
  • STM32—串口

    串口介绍 串行接口简称串口 xff0c 也称串行通信接口或串行通讯接口 xff08 通常指COM接口 xff09 xff0c 是采用串行通信方式的扩展接口 串行接口 xff08 Serial Interface xff09 是指数据一位一位
  • 2021电赛元件清单(评论区有题目预测)

    2021 年全国大学生电子设计竞赛仪器设备和主要元器件及器材清单 本科组 1 仪器设备清单 数字示波器 xff08 100MHz xff0c 双通道 xff09 函数发生器 xff08 50 MHz xff0c 双通道 xff09 任意波信

随机推荐