当前课程知识点:C++语言程序设计进阶 > 第九章 模板与群体数据 > 模板 > 类模板
使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本类型的和用户自定义类型)。
类模板 template <模板参数表> class 类名 {类成员声明};
如果需要在类模板以外定义其成员函数,则要采用以下的形式: template <模板参数表> 类型名 类名<模板参数标识符列表>::函数名(参数表)
#include <iostream> #include <cstdlib> using namespace std; struct Student { int id; //学号 float gpa; //平均分 }; template <class T> class Store {//类模板:实现对任意类型数据进行存取 private: T item; // item用于存放任意类型的数据 bool haveValue; // haveValue标记item是否已被存入内容 public: Store(); T &getElem(); //提取数据函数 void putElem(const T &x); //存入数据函数 }; template <class T> Store<T>::Store(): haveValue(false) { } template <class T> T &Store<T>::getElem() { //如试图提取未初始化的数据,则终止程序 if (!haveValue) { cout << "No item present!" << endl; exit(1); //使程序完全退出,返回到操作系统。 } return item; // 返回item中存放的数据 } template <class T> void Store<T>::putElem(const T &x) { // 将haveValue 置为true,表示item中已存入数值 haveValue = true; item = x; // 将x值存入item } int main() { Store<int> s1, s2; s1.putElem(3); s2.putElem(-7); cout << s1.getElem() << " " << s2.getElem() << endl; Student g = { 1000, 23 }; Store<Student> s3; s3.putElem(g); cout << "The student id is " << s3.getElem().id << endl; Store<double> d; cout << "Retrieving object D... "; cout << d.getElem() << endl; //d未初始化,执行函数D.getElement()时导致程序终止 return 0; }
大家好
欢迎回来继续学习
C++语言程序设计
这一节我们来学习类模板
类模板
是一种很好的机制
它让我们可以为类
去声明一种模式
这样的话呢
我们在类体里面
比如说要定义数据成员啊
还有我们要定义成员函数啊
那么这个数据成员的类型
成员函数的参数类型
返回值类型等等
都可以设置成为
一个抽象数据类型
也就是说
当你要使用这个类模板
去生成真正的实用的类的时候
可以指定你需要什么类型
这样的话呢
我们这个类模板就可以
由编译器为你生成
针对特殊数据类型的类
我们看这是类模板的语法
在这儿呢
我们也是同样用到
这个template关键字
然后尖括里面
也是模板参数表
然后底下呢 class之后
差不多就像我们
声明一个普通类一样
去定义它就可以了
只是
当我们定义一个普通类的时候
类的成员
函数里面用到的这些数据
比如说参数返回值
都需要有一个确定的数据类型
现在呢
我们用类模板的话
可以在模板参数表中
去定义类型参数
也就是说
可以认为它是个抽象数据类型
用一个标识符
一个符号来表示
比如用T来表示
这样类体里面在需要用到
数据类型的时候
就可以用这种抽象
数据类型的标识符来代替
如果说需要在类模板以外
定义它的成员函数
那这个时候呢
都要带上这个template
和模板参数表
那其他部分呢
跟定义一个普通的函数
基本上是一样的
只是还是这个问题
函数体中会用到
模板参数表中的抽象数据类型
下面呢
我们来看一个简单的
类模板示例
在这里我们定义了一个
类模板Store
这个类模板是用来容纳
一个数据项的
一个很小很小的小容器
它只能容纳一个数据项
那这个数据是什么类型的呢
这个类型是在类型参数表中
列出来的一个类型参数
也就是说
在使用的时候
是我们可以指定类型的
那这里另外一个数据呢
是一个确定类型的bool类型的
表示是否已经存入了数据
然后另外我们看
成员函数它的返回值
也可以是个抽象的T类型的
然后成员函数的参数
存入数据这个函数
它的参数也是一个类型参数
所以可以存入
可定制的类型数据
并且提取这个数据
这个Store是构造函数
那我们看函数的实现
这些函数的实现
我们可以看到
实际上每一个成员函数
它都是一个函数模板
跟我们前面讲的
实现函数模板的方式
是一样的
好 在主函数中
我们准备好一些数据
然后往里面存
首先呢
我们要定义两个用来存储
int数据的Store类型
Store int这种类型
那看到我们在程序中
给出的这个类型参数int以后呢
编译器就会用int去替换t
实际上为我们生成了一个
这样的Store类
接着我们就可以调用
putElem的函数
将3 将-7加到这两个对象
s1 s2里面去
当然添加进去以后
我们可以取出来再验证一下
那接下来呢
我们在这儿又构造了一个
结构体Student类的对象
Student结构体对象
然后
我们这一次去构造对象s3的时候
就指定这个类型参数是Student
于是编译器又为我们生成了一个
这样的类
这是我们简单的一个
示意性的说明
不是说原样生成一模一样
这样的原代码
至于编译器怎么处理的呢
这个是根据
每个编译器的实现方案去解决的
但是示意性的可以告诉大家
大致就是生成了这样一个类
里面的T都替换成Studnet
然后
我们又可以构造这个对象s3
同样的道理
当我们指定这个类型参数
是double的时候
也会用double替换T
为我们生成一个新的类
然后就构造对象D
那在构造了对象D以后
我们去制造了一个错误
也就是说
我们没有往里面putElem
你看这个s1 s2 s3对象
构造好以后
我们都先将一个数据给它存进去
然后再调用getElem去取出来
但是构d对象以后
我们直接就去getElem取出来
这个就是测试一下
我们这个类里面
它的错误处理功能
也就是
调用getElem的时候呢
如果说没有存过这个数据的话
它就会报错的
所以在这儿程序就出错了
-导学
--导学
-继承的基本概念和语法
-第七章 继承与派生--继承的基本概念和语法习题
-继承方式
-第七章 继承与派生--继承方式
-基类与派生类类型转换
-第七章 继承与派生--基类与派生类类型转换
-派生类的构造和析构
--派生类的构造函数
--派生类的析构函数
--第七章 继承与派生--派生类的构造和析构
-派生类成员的标识与访问
--虚基类
-第七章 继承与派生--派生类成员的标识与访问
-小结
--小结
-综合实例
--第七章综合实例
-实验七
--实验七
-导学
--导学
-第八章 多态性--导学
-运算符重载
--运算符重载的规则
-第八章 多态性--运算符重载
-虚函数
--虚函数
--虚析构函数
--虚表与动态绑定
-第八章 多态性--虚函数
-抽象类
--抽象类
--第八章 多态性--抽象类
-override与final
-第八章 多态性--override与final
-小结
--第八章小结
-综合实例
--第八章综合实例
-实验八
--实验八
- 第八章讲义
-导学
--导学
-模板
--函数模板
--类模板
-第九章 模板与群体数据--模板
-线性群体
--线性群体的概念
-第九章 模板与群体数据--线性群体
-数组
--数组类模板
-链表
--链表类模板
-第九章 模板与群体数据--链表
-栈
--栈类模板
--栈类模板课后习题
--例9-9 栈的应用课后习题
-队列
--队列类模板
-第九章 模板与群体数据--队列
-排序
--排序概述
--插入排序
--选择排序
--交换排序
-第九章 模板与群体数据--排序
-查找
--查找
--查找课后习题
-小结
--小结
-综合实例
--综合实例
-实验九
--实验九
- 第九章讲义
-导学
--导学
-泛型程序设计及STL的结构
--STL简介
-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构
-迭代器
--迭代器
-第十章 泛型程序设计与C++标准模板库--迭代器
-容器的基本功能与分类
-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类
-顺序容器
--顺序容器的特征
--第十章 泛型程序设计与C++标准模板库--顺序容器
-关联容器
--集合
--映射
-第十章 泛型程序设计与C++标准模板库--关联容器
-函数对象
--函数对象
--函数适配器
-算法
--算法
-小结
--第十章小结
-综合实例
--综合实例
-实验十
--实验十
- 第十章讲义
-导学
--导学
-I/O流的概念及流类库结构
-第十一章 流类库与输入/输出--I/O流的概念及流类库结构
-输出流
--输出流概述
--向文本文件输出
--向二进制文件输出
--向字符串输出
-第十一章 流类库与输入/输出--输出流
-输入流
--输入流概述
--输入流应用举例
--从字符串输入
-第十一章 流类库与输入/输出--输入流
-输入/输出流
--输入/输出流
-第十一章 流类库与输入/输出--输入/输出流
-小结
--小结
-综合实例
--综合实例
-实验十一
--实验十一
- 第十一章讲义
-导学
--第12章导学
-异常处理的思想与程序实现
-第十二章 异常处理--异常处理的思想与程序实现
-异常处理中的构造与析构
-第十二章 异常处理--异常处理中的构造与析构
-标准程序库异常处理
-第十二章 异常处理--标准程序库异常处理
-小结
--第12章小结
-综合实例
--综合实例
-实验十二
--实验十二
- 第十二章讲义