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

原文地址:https://www.cnblogs.com/findumars/p/9302615.html

时间: 2024-10-13 22:22:01

C++模板类代码只能写在头文件?的相关文章

编程算法 - 求1+2+...+n(模板类) 代码(C++)

求1+2+...+n(模板类) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 求1+2+...+n, 要求不能使用乘除法\for\while\if\else\switch\case等关键字及条件判断语句(A?B:C). 可以使用模板类求解, 输入模板参数, 进行递归调用, 每次递归值减1, 至模板参数为1时, 显示调用结束模板类. 代码: /* * main.cpp * * Created on: 2014.7.12 * Author

C++模板的定义一定要在头文件中 - LNK2019无法链接的外部符号,LNK1120无法解析的外部命令

编译器在模板函数的调用处,才最终知道如何生成代码. 模板函数的不能像普通的成员函数那样声明于头文件而定义在cpp源文件,而是一定要定义在头文件中. 若像普通成员函数那样声明和定义,单个文件可以编译通过,但被其他文件使用时会报LNK2019,LNK1120错误: 原文地址:https://www.cnblogs.com/dylanchu/p/12315493.html

【转】模板类的声明与实现必须同时放在头文件中

著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:余天升链接:http://www.zhihu.com/question/20630104/answer/15722407来源:知乎 模板类的实现,脱离具体的使用,是无法单独的编译的:把声明和实现分开的做法也是不可取的,必须把实现全部写在头文件里面.为了清晰,实现可以不写在class后面的花括号里面,可以写在class的外面. 解释: C++中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,

C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?

C++ Template>第六章讲过这个问题组织模板代码有三种方式1.包含模型(常规写法 将实现写在头文件中)2.显式实例化(实现写在cpp文件中,使用template class语法进行显式实例化)3.分离模型(使用C++ export关键字声明导出) 第三种方式理论最优,但是实际从C++标准提出之后主流编译器没有支持过,并且在最新的C++11标准中已经废除此特性,export关键字保留待用.那么实际上能够使用的实现分离也就只有显式实例化 比较有意思的是,<C++ Template>书

关于模板类

今天第一次写了模板类.在写的时候把声明和实现分开后,即.h文件和.cpp文件.在链接时提示找不到模板类中某个方法的定义. 查阅资料发现:模板类在使用的时候.编译器需要找到它的定义. 即: 编译器使用模板,通过更换模板参数来创建数据类型.这个过程就是模板实例化(Instantiation).  从模板类创建得到的类型称之为特例(specialization).   模板实例化取决于编译器能够找到可用代码来创建特例(称之为实例化要素,  point of instantiation).  要创建特例

模板类与类模板、函数模板与模板函数等的区别

在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替换混淆使用.下面我想彻底辨清几个术语,这样就可以避免很多概念上的混淆和使用上的错误.这几个词是: 函数指针——指针函数 数组指针——指针数组 类模板——模板类 函数模板——模板函数 最终在使用中,我们就可以让它们实至名归,名正言顺. 1.函数指针——指针函数   函数指针的重点是指针.表示的是一个指针,它指向的是一个函数,例子: int   (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.例子:

在类的头文件中尽量少引入其他头文件 &lt;&lt;Effective Objective-C&gt;&gt;

与C 和C++ 一样,Objective-C 也使用"头文件"(header file) 与"实现文件"(implementation file)来区隔代码.用Objective-C 语言编写"类"(class)的标准方式为:以类名做文件名,分别创建两个文件,头文件后缀用.h,实现文件后缀用.m.创建好一个类之后,其代码看上去如下所示: // EOCPerson.h #import <Foundation/Foundation.h>

怎样用boost::serialization去序列化派生模板类(续)

在 怎样用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写测试用例时一直出现编译错误,调了很久也没跳出来,今天偶然试了一下...居然调了出来. 先看看变异错误的代码(...看不出有错,可是编译就有错). 基类代码: class base_class { public: base_class(int m=0) : base_member_(0) {} virtual ~base_class() {} virtual void print_dat

如何用boost::serialization去序列化派生模板类(续)

在 如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来. 先看看变异错误的代码(...看不出有错,但是编译就有错). 基类代码: class base_class { public: base_class(int m=0) : base_member_(0) {} virtual ~base_class() {} virtual void print_da