C++中函数模版与类模版
1、什么是模板?
(1)可以这样来解释这个问题,例如当我们需要定义多个函数,而这个函数功能其实都是一样的,例如两个数相加的函数,
只是相加的两个数的类型不相同而已,这就导致我们需要定义多个函数;当我们使用了函数模板之后,我们只需要定义
一个函数模板,这个函数模板的功能就是实现两个数相加的操作,而且可以传入自己指定的数据类型,这样我们就不用定义
多个函数了,所以可以认为,模板就是一种可以产生一系列功能相同而数据类型不同的函数或者是类的 "机器"。
(2)模板的形式:函数模板、类模板
(3)模板的声明格式
函数模板:
template<typename 类型参数>
返回类型 函数名(模板形参表)
{
函数体
}
或
template<class 类型参数>
返回类型 函数名(模板形参表)
{
函数体
}
类模板:
template <typename 类型参数>
class 类名
{
类成员声明
}
或
template <class 类型参数>
class 类名
{
类成员声明
}
在上面的template后面的参数可以是多个,也可以是一个,而且修饰词typename和class可以混用,可以认为他们两个关键字没有什么区别,都可以使用;
template后面的"<>"尖括号可以紧跟在template关键字后面,也可以用空格来隔开;
(4)需要注意的是:typename或者是class指定的是一种数据类型,其实除了可以指定数据类型之外,还可以指定某种数据类型的变量,例如下面的
template <typename 形参名,class 形参名,int 形参名, double 形参名, ......>
typename和class后面的表示的是某种数据类型的形参名,将来在使用模板函数的时候传入自己指定的数据类型;而int和double后面的表示的是
这种数据类型的变量,将来在使用模板函数的时候自己传入自己的变量。所以对于模板的形参总共就是分为这两类:类型形参和非类型形参。
2、模板函数和模板类的使用
函数模板定义及其使用:
#include <iostream>
using namespace std; template <typename T> // 声明函数模板
static T Add1(T a, T b)
{
return (a + b);
} template <class T, int count> // 声明函数模板
static void Print(T a)
{
int i = ; for (i = ; i < count; i++)
cout << a << " ";
cout << endl;
} int main(void)
{
cout << Add1<int>(, ) << endl; // 使用模板函数
Print<int, >(); // 使用模板函数
return ;
}
类模板定义及其使用:
#include <iostream>
using namespace std; template <typename T, int Ksize, int Kval>
class Array{
public:
Array(void); // 构造函数
~Array(void) { delete[]p_Arr; p_Arr = NULL; } // 析构函数 类内定义方式
void display(void);
private:
T *p_Arr;
}; template <typename T, int Ksize, int Kval> // 类外定义方式
Array<T, Ksize, Kval>::Array(void)
{
p_Arr = new T[Ksize];
int i = ; for (i = ; i < Ksize; i++)
p_Arr[i] = Kval;
} template <typename T, int Ksize, int Kval> // 类外定义方式
void Array<T, Ksize, Kval>::display(void)
{
int i = ; for (i = ; i < Ksize; i++)
cout << p_Arr[i] << " ";
cout << endl;
} int main(void)
{
Array<int, , > arr;
arr.display();
return ;
}
运行结果分别如下所示:

(1)对于模板函数的使用需要注意的是:我们需要在函数名之后添加一对尖括号,将需要传给函数模板的参数写进去: Add1<int>(10, 20);
但是其实不加 <int> 也是可以的,但是前提条件是函数的参数类型都是相同的,否则就会编译出错:
Add1(10, 20) // 这样是可以的,因为10 和 20 数据类型相同
Add1(10, 20.0) // 这就不行,数据类型不相同
(2)对于类模板需要注意的是:除了在类模板声明前加上 template <......> 之外,如果成员函数是在类内定义倒没什么可说的,如果是在类外定义的,那么就需要注意了:
每个在类外定义的所有成员函数之前都要加上 template <......>,而且函数名前面还要加上 <.....>,里面的内容是参数名,如下所示:
template <typename T, int Ksize, int Kval> // 类外定义方式
Array<T, Ksize, Kval>::Array(void) { }
(3)通过类模板来定义一个类对象的时候也是和函数差不多,也是需要加上 <...>,将要传给类模板的参数写进去即可: Array<int, 10, 10> arr;
2、模板本身不会占用内存空间,而定义的模板函数或者是模版类才会占用内存空间。
3、函数模板与同名非模板函数也可以重载。
#include <iostream>
using namespace std; template <typename T> // 声明函数模板
static T Add(T a, T b)
{
cout << "模板函数" << endl;
return (a + b);
} static int Add(int a, int b) // 普通函数
{
cout << "普通函数" << endl;
return (a + b);
} int main(void)
{
cout << Add(, ) << endl;
return ;
}
运行结果如下:从结构可以看出来,函数模板与同名非模板函数也可以重载,而且当我们调用函数的时候优先调用的是普通的函数,而不是模板函数。

4、在template语句和函数模板定义语句之间是不允许插入其他的语句,并且一个 template<....> 只能对应一个模板的声明,而不用使用一个 template<....> 来声明多个函数模板或者是类模板。
C++中函数模版与类模版的更多相关文章
- 为什么 c++中函数模板和类模板的 声明与定义需要放到一起?
将模板的声明与定义写在一起实在很不优雅.尝试用“传统”方法,及在.h文件里声明,在.cpp文件里定义, 然后在main函数里包含.h头文件,这样会报链接错误.why!!!!!!!!!!!!! 这是因为 ...
- c++ 类模版、成员函数模版、函数模版 用法
C++函数模版与类模版. template <class T> void SwapFunction(T &first, T &second){ }//函数模版 templa ...
- 类模版的static成员
类模版中声明static成员 template <class T> class Foo { public: static size_t count() { ++ctr; cout < ...
- C++ 类模板三(类模版中的static关键字)
//类模版中的static关键字 #include<iostream> using namespace std; /* 类模板本质上是c++编译器根据类型参数创建了不同的类, c++编译器 ...
- C++ 类模板二(类模版与友元函数)
//类模版与友元函数 #include<iostream> using namespace std; template<typename T> class Complex{ p ...
- 初探C++类模版学习笔记
类模板 实现:在定义类的时候给它一个或多个參数,这个些參数表示不同的数据类型. -->抽象的类. 在调用类模板时, 指定參数, 由编译系 ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数
话接上篇.通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽. 但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功 ...
- VC6.0中重载操作符函数无法访问类的私有成员
整理日: 2015年03月18日 在 C++ 中,操作符(运算符)可以被重载以改写其实际操作.同时我们可以定义一个函数为类的朋友函数(friend function)以便使得这个函数能够访问类的私有成 ...
随机推荐
- zz 跟风小结一下孕期~
http://www.newsmth.net/nForum/#!article/FamilyLife/1754069968 发信人: milkcat (牛奶猫养了一只牛奶猫(*^__^*) 嘻嘻……) ...
- 10件在PHP7中不要做的事情
10件在PHP7中不要做的事情 1. 不要使用mysql_函数 这一天终于来了,从此你不仅仅“不应该”使用mysql_函数.PHP 7 已经把它们从核心中全部移除了,也就是说你需要迁移到好得多的mys ...
- vmware player 在windows下nat模式中的端口映射
1.设置虚拟机nat共享的网卡为固定ip vmware虚拟机使用nat网络时,是VMware Network Adapter VMnet8网卡提供的nat服务.查看VMware Network Ada ...
- NLTK在自然语言处理
nltk-data.zip 本文主要是总结最近学习的论文.书籍相关知识,主要是Natural Language Pracessing(自然语言处理,简称NLP)和Python挖掘维基百科Infobox ...
- js基础篇string&&array(应YX同学面试复习要求 - -)
js中的数据类型一共有五个基本数据类型,分别是undefined,null,boolean,number,string. js中的Object类型中包括两大类型:Function类型和array类型. ...
- C语言:宽字符集操作函数(unicode编码)
C语言:宽字符集操作函数(unicode编码) 字符分类: 宽字符函数 普通C函数描述 iswalnum() isalnum() 测试字符是否为数字或字母 iswalpha() isalpha() 测 ...
- 解决标准FPGA资源丰富却浪费的问题
FPGA以计算速度快.资源丰富.可编程著称,之前一直应用于高速数字信号领域和ASIC验证.随着逻辑资源的丰富和编程工具的改进,FPGA在机器学习和硬件加速上得到越来越多的重视,目前数据中心已经大量采用 ...
- [模板]ST表浅析
ST表,稀疏表,用于求解经典的RMQ问题.即区间最值问题. Problem: 给定n个数和q个询问,对于给定的每个询问有l,r,求区间[l,r]的最大值.. Solution: 主要思想是倍增和区间d ...
- 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #7 Cgroup、Namespace、Linux容器
HACK #7 Cgroup.Namespace.Linux容器 本节将介绍Cgroup与Namespace以及通过这两个功能实现的容器功能.CgroupCgroup(control group)是将 ...
- OpenCL 第一个计算程序,两向量之和
▶ 一个完整的两向量加和的过程,包括查询平台.查询设备.创建山下文.创建命令队列.编译程序.创建内核.设置内核参数.执行内核.数据拷贝等. ● C 代码 #include <stdio.h> ...