这个问题,实际上我几年前就遇到了。最近写个模板类玩的时候,再次遇到。

  当我非常仔细的将定义和实现分开,在头文件中保留了最少的依赖后,一切就绪.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. 编程算法 - 求1+2+...+n(模板类) 代码(C++)

    求1+2+...+n(模板类) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 求1+2+...+n, 要求不能使用乘除法\for\whil ...

  2. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  3. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  4. 通过宏定义将__declspec(dllexport)与__declspec(dllimport)的转化,实现库代码和使用代码使用同一份头文件

    我们知道,在VC编程中,如果要编译成动态链接库,需要将函数.变量.类等导出,这时使用__declspec(dllexport).使用动态链接库时,需要在声明的时候有使用__declspec(dllim ...

  5. 20140315 模板类pair的用法 2、visual 2010调整代码格式是ctrl+k+

    1.模板类pair的用法 包含头文件#include<utility>   http://blog.csdn.net/laixingjun/article/details/9005200 ...

  6. C++头文件中#pragma once与#ifndef……#define……#endif

    两者功能一样,防止重复包含被多次编译.建议头文件加入#pragma once C++头文件开头的两句与结尾的一句#ifndef <标识>#define <标识>类代码#endi ...

  7. C++头文件中的模板类

    C++头文件中的模板类 这已经是我的第三篇关于头文件的博客了,没想到我还是踩了个巨坑. 大家都知道要在头文件里声明类成员,在源文件中实现. 但是今天写数据结构作业,在头文件(Stack.h)定义了一个 ...

  8. C++中头文件(.h)和源文件(.cpp)都应该写些什么

    头文件(.h): 写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但一般来说不写出具体的实现. 在写头文件时需要注意,在开头和结尾处必须按照如下样式加上预编译语句(如下): ...

  9. 原理:C++为什么一般把模板实现放入头文件

    写在前面 本文通过实例分析与讲解,解释了为什么C++一般将模板实现放在头文件中.这主要与C/C++的编译机制以及C++模板的实现原理相关,详情见正文.同时,本文给出了不将模板实现放在头文件中的解决方案 ...

随机推荐

  1. JSONObject与JSONArray的使用区别

    1.JSON 1. 创建一个JSONObject对象: package com.yunos.tv.video.resource.controller.web; import java.util.Arr ...

  2. PostgreSQL Replication之第三章 理解即时恢复(1)

    到现在为止,您已经掌握了一定的理论.因为生活不仅由理论组成(它可能同样重要),是时候深入实际的工作了. 本章的目标是让您明白如何恢复数据到一个给定的时间点.当您的系统崩溃或者有人意外地删除了一个表,不 ...

  3. Python3基础笔记--常用模块

    目录: 参考博客:Python 之路 Day5 - 常用模块学习 Py西游攻关之模块 一.time模块 二.random模块 三.os模块 四.sys模块 五.hashlib模块 六.logging模 ...

  4. vue分页组件火狐中出现样式问题

    分页的操作到了火狐浏览器会样式 怎么解决? 其实就是将input的type属性变成了text,因为number属性会变成上下的小箭头

  5. POJ2976 Dropping tests(01分数规划)

    题意 给你n次测试的得分情况b[i]代表第i次测试的总分,a[i]代表实际得分. 你可以取消k次测试,得剩下的测试中的分数为 问分数的最大值为多少. 题解 裸的01规划. 然后ans没有清0坑我半天. ...

  6. NOIP2016 天天爱跑步(树上差分)

    题意 给定一棵树,从时刻 0 开始,有若干人从 S[i] 出发向 T[i] 移动,每单位时刻移动一条边 对于树上每个点 x,求 w[x]  时刻有多少人恰好路过 x N,M≤300000 题解 从上午 ...

  7. HNU 12876 Quite Good Numbers 完美数变形

    筛法是一种很快的方法,贴代码纪念一下. 做法很像筛法 #include <iostream> #include <cstdio> #include <cstring> ...

  8. 智能指针的->和 * 重载

  9. 小白学开发(iOS)OC_ 经常使用结构体(2015-08-14)

    // //  main.m //  经常使用结构体 // //  Created by admin on 15/8/13. //  Copyright (c) 2015年 admin. All rig ...

  10. 28. Brackets安装angularjs插件

    Brackets是Adobe公司研发的一款开源WEB前端开发框架,界面清爽简约,代码提示功能比较强大,而且支持第三方插件,其提供的插件库中有大量的对Brackets感兴趣的开发人员所开发的插件,使用者 ...