c++模板是编译器构造具体实例类型的模型,使类型参数化,是泛型编程的基础,泛型就是独立于特定类型。

一、模板分为函数模板和类模板两种。

  函数模板:template <class 形参名,class 形参名,......>   返回值  函数名(参数列表...){}

  类模板:template  <class 形参名,class 形参名,......>  class  类名{ };

如上是实现函数模板和类模板的方法。在使用时,模板函数和普通函数一致,c++采用参数推导的方式自动生成与传入实参一致的函数实例。类模板在使用时,需要对类型参数赋值,如:

  Templateclass<类型实参> TempClass;

编译器由此生成传入实参对应的实例类。

注意模板实例化发生在编译阶段,大量使用模板的一个弊端就是造成大量代码生成,使编译变慢。

二、模板的另一个特点是,模板类的声明和实现不能分离,即都在.h文件中。有两中方式实现模板声明和实现的分离。

1、使用.hpp的方式。将模板实现放在.hpp中,并在.h文件最后中加入.hpp的声明。

2、使用显式的模板实例声明,如:

//template.h
#ifndef TEMPLATE_H_
#define TEMPLATE_H_ #include <iostream> //#include
template <typename T>
class TemplateDemo{
public:
TemplateDemo(T & data, int size);
private:
T *_data;
protected:
}; #endif //TEMPLATE_H_ //template.cpp
#include "template.h" template <typename T>
TemplateDemo<T>::TemplateDemo(T & data, int size){
if( size != ){
this->_data = new T[size];
for(int i = ; i < size; i++){
this->_data[i] = data;
}
}
} template class TemplateDemo<std::string>;
template class TemplateDemo<int>;

三、为什么模板类不能够声明和定义分离?

模板类是编译器生成具体的类的依据,只有模板被使用时才会编译。首先一般编译器都是以一个.cpp文件为一个编译单元,如果模板类的声明和实现是分离的,那么对模板类的定义文件编译,生成.o文件,此时只有模板,没有模板的实例类。c++编译器的工作流程分为预处理、编译、汇编、链接,而模板实例化发生在编译期间,当编译器没有找到模板类的一个特例时,它会认为该特例在另外的文件中(.o或.so),而将问题交给链接器去处理,但是模板的实现文件中没有该实例,无法找到符号,所以一般这种问题的抱错都是”ld error“。

那么为什么模板不被使用就无法编译呢。我们知道,c语言对内存的管理是底层的面向系统的,如果类型参数化的模板类而言,无法得知模板的类型,就无法得知模板类的占用内存。编译器无法为一个不知道大小的类分配内存。所谓模板类,不是一个类,而是一个生成类的模板。

c++模板使用及实现模板声明定义的分离的更多相关文章

  1. c++类模板中静态成员变量的声明定义

    我们知道,c++中,类的静态成员是要在.cpp文件中定义的,如果在.h中定义,会出现重复定义. 但是在写类模板时,一般所有的代码都是放在.h文件中的,如果要做分离是一件很麻烦的事.那如果出现了静态成员 ...

  2. c++模板函数声明定义分离编译错误详解

    今天看到accelerated c++上有个简单的vector容器的实现Vec,就再vs2008上编译了下: ///// Vec.h #ifndef GUARD_VEC_H #define GUARD ...

  3. C++ 类模板一(类模板的定义)

    //类模版语法 #include<iostream> using namespace std; /* 类模板和函数模板深入理解 1.编译器并不是把函数模板处理成能处理任何类型的函数 2.编 ...

  4. C++ 函数模板一(函数模板定义)

    //函数模板定义--数据类型做参数 #include<iostream> using namespace std; /* 函数模板声明 1.函数模板定义由模板说明和函数定义组成,并且一个模 ...

  5. 使用 c++ 模板显示实例化解决模板函数声明与实现分离的问题

    问题背景 开始正文之前,做一些背景铺垫,方便读者了解我的工程需求.我的项目是一个客户端消息分发中心,在连接上消息后台后,后台会不定时的给我推送一些消息,我再将它们转发给本机的其它桌面产品去做显示.后台 ...

  6. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  7. C++模板学习:函数模板、结构体模板、类模板

    C++模板:函数.结构体.类 模板实现 1.前言:(知道有模板这回事的童鞋请忽视) 普通函数.函数重载.模板函数 认识. //学过c的童鞋们一定都写过函数sum吧,当时是这样写的: int sum(i ...

  8. 模板类的约束模板友元函数:template friend functions

    本来这篇博客是不打算写的,内容不是很难,对于我自己来讲,更多的是为了突出细节. 所谓template friend functions,就是使友元函数本身成为模板.基本步骤:1,在类定义的前面声明每个 ...

  9. C++—模板(1)模板与函数模板

    1.引入 如何编写一个通用加法函数?第一个方法是使用函数重载, 针对每个所需相同行为的不同类型重新实现这个函数.C++的这种编程机制给编程者极大的方便,不需要为功能相似.参数不同的函数选用不同的函数名 ...

随机推荐

  1. Matlab绘图基础——用print函数保存图片(Print figure or save to file)

    print(figure_handle,'formats','-rnumber','filename')  %将图形保存为png格式,分辨率为number的(默认为72),最好指定的分辨率大一点,否则 ...

  2. 如何使用 RESTClient 调试微信支付接口

    我们知道微信支付使用http协议进行api调用,body 使用xml格式,使用的一般http在线调试工具,无法进行xml数据的post. RESTClient 做的很好,支持各种http 方法,bod ...

  3. Java基础学习笔记十六 集合框架(二)

    List List接口的特点: 它是一个元素存取有序的集合.例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的. 它是一个带有索引的集合,通过索引就可以精 ...

  4. p-value

    p-value p-value翻译为假定值,假设几率.我们在生物信息中通常使用p值方法(P-Value, Probability, Pr)来做检验.那么p-value是什么呢?其实P-value就是一 ...

  5. I know 项目Alpha冲刺随笔集

    Alpha冲刺 Day 1 Alpha冲刺 Day 2 Alpha冲刺 Day 3 Alpha冲刺 Day 4 Alpha冲刺 Day 5 Alpha冲刺 Day 6 Alpha冲刺 Day 7 Al ...

  6. 【Alpha版本】冲刺阶段 - Day3 - 逆风

    今日进展 袁逸灏:右上角两个按键的添加与实现监听(5h) 刘伟康:继续借鉴其他 alpha 冲刺博客,由于我们组的App原型可以在 alpha 阶段完成,所以不需要墨刀工具展示原型(2h) 刘先润:更 ...

  7. 201621123040 《Java程序设计》第1周学习总结

    1.本周学习总结 关键词 JAVA概述 HelloWorld JDK JRE JVM JAVA基础语法 相关联系 通过一周的学习,我对JAVA有了初步的了解,JAVA是一种优秀的跨平台编写代码的应用平 ...

  8. Alpha冲刺Day4

    Alpha冲刺Day4 一:站立式会议 今日安排: 我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.完成了数据库管理员模块.因企业人员与第三方人员模块存在大量的一致性,故我们团 ...

  9. 201621123068 Week04-面向对象设计与继承

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:继承.多态.重载.关键字.父类与子类 1.2 尝试使用思维导图将这些关键词组织起来. 2. 书面作业 1. 面向对象设计(大 ...

  10. c/cpp语言链表连接部分详解

    核心代码: ①pTail->next = pNew; ②pNew->next = NULL; ③pTail = pNew; 设结构体名称为 struct ST: 注:方框代表分配的内存空间 ...