C++模板类代码只能写在头文件?
这个问题,实际上我几年前就遇到了。最近写个模板类玩的时候,再次遇到。
当我非常仔细的将定义和实现分开,在头文件中保留了最少的依赖后,一切就绪.cpp单独编过。但是当使用的时候,就会报告所有的函数调用都没有实现。按常规.h/.cpp而言这是不可能的。但是模板类就是这么独特。简单说说他的原因,也备自己将来遗忘:
从语法角度而言,是没有强制要求说模板代码的声明和实现不可以分开。那么当分离的声明和实现写好后,单独编译.cpp是可以通过的,但是生成的.o文件却非常小,只有一个原因:确实没有任何实现代码!————不知道用什么类型参数套用模板。
因为模板类需要在使用到的地方利用声明模板的typename或者class参数的时候,才会即时生成代码。那么当我把模板声明和实现分开的时候,这个即时过程因为编译器只能通过代码include“看到”头文件而找不到模板实现代码,所以会产生链接问题。这也是为什么几乎都会建议模板类和声明和实现都写在头文件。
如果刚接触c/c++编写的朋友可能还不是很明白。编译器面对巨量代码的时候,也是以一个一个的.cpp/.c文件作为基本单元,根据代码的include包含找到声明,翻译代码产生.o文件。注意他们每个cpp/c文件都是相互独立完成自己工作的,对于缺少的部分,如果妥善声明,会留待链接过程的时候产生引用关系。 那么刚才说的模板类实现代码,编译它的时候因为不知道套用什么参数,实际上没有任何有用的内容存在于.o文件当中。而在使用模板类的地方指定了类型参数,编译器这才开始根据模板代码产生有用的.o编码,可是这些内容放在了使用模板的代码产生的.o文件当中。如果编使用模板代码的时候,通过include包含“看不到”模板的实现代码,这些所有的缺失,到链接阶段就无法完成。
所以最后的结论是:请老老实实把模板的实现和声明都写在头文件吧。如果你很有想法有个性,可以坚持,然后试试#include “xxxx.cpp” 这样屌炸的代码。
https://blog.csdn.net/jinzeyu_cn/article/details/45795923
C++模板类代码只能写在头文件?的更多相关文章
- 编程算法 - 求1+2+...+n(模板类) 代码(C++)
求1+2+...+n(模板类) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 求1+2+...+n, 要求不能使用乘除法\for\whil ...
- linux内核中链表代码分析---list.h头文件分析(一)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...
- linux内核中链表代码分析---list.h头文件分析(二)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...
- 通过宏定义将__declspec(dllexport)与__declspec(dllimport)的转化,实现库代码和使用代码使用同一份头文件
我们知道,在VC编程中,如果要编译成动态链接库,需要将函数.变量.类等导出,这时使用__declspec(dllexport).使用动态链接库时,需要在声明的时候有使用__declspec(dllim ...
- 20140315 模板类pair的用法 2、visual 2010调整代码格式是ctrl+k+
1.模板类pair的用法 包含头文件#include<utility> http://blog.csdn.net/laixingjun/article/details/9005200 ...
- C++头文件中#pragma once与#ifndef……#define……#endif
两者功能一样,防止重复包含被多次编译.建议头文件加入#pragma once C++头文件开头的两句与结尾的一句#ifndef <标识>#define <标识>类代码#endi ...
- C++头文件中的模板类
C++头文件中的模板类 这已经是我的第三篇关于头文件的博客了,没想到我还是踩了个巨坑. 大家都知道要在头文件里声明类成员,在源文件中实现. 但是今天写数据结构作业,在头文件(Stack.h)定义了一个 ...
- C++中头文件(.h)和源文件(.cpp)都应该写些什么
头文件(.h): 写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但一般来说不写出具体的实现. 在写头文件时需要注意,在开头和结尾处必须按照如下样式加上预编译语句(如下): ...
- 原理:C++为什么一般把模板实现放入头文件
写在前面 本文通过实例分析与讲解,解释了为什么C++一般将模板实现放在头文件中.这主要与C/C++的编译机制以及C++模板的实现原理相关,详情见正文.同时,本文给出了不将模板实现放在头文件中的解决方案 ...
随机推荐
- Nginx-虚拟主机配置问题
Nginx-虚拟主机配置问题 标签(空格分隔): linux,php,nginx,larave 这两天突然想配置lnmp环境,学习下Nginx配置结果就遇到了下边的问题 Nginx: server下的 ...
- ReactiveCocoa 中 RACSignal 是如何发送信号的
https://juejin.im/post/5829f4c3570c350063c436ac 前言 ReactiveCocoa是一个(第一个?)将函数响应式编程范例带入Objective-C的开源库 ...
- bzoj1457: 棋盘游戏 SG函数 Nim
Code: #include<cstdio> #include<cstring> using namespace std; #define maxn 1003 #define ...
- 今日SGU 5.29
sgu 299 题意:给你n个线段,然后问你能不能选出其中三个组成一个三角形,数字很大 收获:另一个大整数模板 那么考虑下为什么如果连续三个不可以的话,一定是不存在呢? 连续上个不合法的话,一定是 a ...
- Unity Camera中心点的偏移
在VR 中,如果镜片的中心轴,和屏幕的中心轴不在一条线上, 就会出现无论如何调节IPD,看到的图像都不清晰,这时候,要修改Camera的投影矩阵, 只需要一句代码就能搞定: Camera.main.p ...
- Spring学习总结(13)——Spring+Log4j+ActiveMQ实现远程记录日志
应用场景 随着项目的逐渐扩大,日志的增加也变得更快.Log4j是常用的日志记录工具,在有些时候,我们可能需要将Log4j的日志发送到专门用于记录日志的远程服务器,特别是对于稍微大一点的应用.这么做的优 ...
- 洛谷 P1443 马的遍历
P1443 马的遍历 题目描述 有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步 输入输出格式 输入格式: 一行四个数据,棋盘 ...
- crm使用soap删除字段
//C# 代码: //DeleteAttributeRequest request = new DeleteAttributeRequest(); //request.EntityLogicalNam ...
- 小白学开发(iOS)OC_ 经常使用结构体(2015-08-14)
// // main.m // 经常使用结构体 // // Created by admin on 15/8/13. // Copyright (c) 2015年 admin. All rig ...
- Task Scheduler
https://technet.microsoft.com/en-us/library/cc748993(v=ws.11).aspx#BKMK_winui If Task Scheduler is n ...