IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 一篇文章读懂类模板 -> 正文阅读

[C++知识库]一篇文章读懂类模板

文章摘自:c++从入门到精通(第四版 清华大学出版社)

使用template关键字不仅可以定义函数模版,也可以定义类模板。类模板代表一族类,是用来描述通用数据类型或处理方法的机制。它使类中的成员函数和数据成员可以取任意的数据类型。类模板可以说是说是用类生成类,减少了类的定义数量。

目录

1.类模板的定义与声明:

2.简单类模板

3.默认模板参数

4. 为具体类型的参数提供默认值

5.有界数组模版


1.类模板的定义与声明:

类模板的一般定义形式如下:

template<类型形式参数表>class 类模板名
{
  //类模版体
 }

类模板成员函数形式定义如下:

template<类型形式参数表>
返回类型 类模版名 <类型名表>::成员函数名(形式参数列表)
{
  //函数体
}

template是关键字,类型形式参数表与模版定义相同。类模板的成员函数定义时的类模板名要与类模板定义时一致。类模版不是一个真实的类,需要重新生成类,生成类形式如下:

类模板名<类型实在参数表>

用新生成的类定义对象的形式如下:

类模版名<类型实在参数表> 对象名

其中类型实在参数表应与该类模板中类型形式参数表匹配。用类模板生成的类称为模板类。类模板和模板类不是同一个概念,类模板是模板的定义,不是真实的类,定义要用到类型参数,模板类本质上和普通类相同,它是类模板的类型参数实例化后得到的类。

定义一个容器的类模板,程序代码如下:

template<class Type>
class Container{
	Type tltem;
	public:
		Container(){};
		void begin(const Type& tNew);
		void end(const Type& tNew);
		void insert(const Type& tNew);
		void empty(const Type& tNew);
};

和普通类一样,需要对类模板成员函数进行定义,程序代码如下:

void Container<Type>::begin(const Type& tNew)//容器的第一个元素
{
  tltem=tNew;
}
void Container<Type>::end(const Type& tNew){//容器的最后一个元素 
  tltem=tNew;
}
void Container<Type>::insert(const Type& tNew){//向容器中插入元素 
  tltem=tNew;
}
void Container<Type>::empty(const Type& tNew){//清空容器
  tltem=tNew;
}

将模板类的参数设置成整型,然后用类模板声明对象,程序代码如下:

Container<int> myContainer;//声明Container<int>类对象

声明对象后,就可以调用类成员函数,程序代码如下:

int i=10;
myContainer.insert(i);

在类模板定义中,类型形式参数表中的参数也可以是其他类模板,例如:

template<template<class A>class B>
class CBase{
 private:
 B<int> m_n;
}

类模板也可以进行继承,例如:

template<class T>
class CDerived public T
{
	public:
	CDrived();
};
template <class T>
CDerive<T>::CDerived():T()
{
	cout<<""<<endl;
}
int main(void){
	CDrived<CBase1>D1;
	CDrived<CBase1>D1;
}

T是一个类,CDerived继承自该类,CDerived可以对类T进行拓展。

2.简单类模板

类模板中的类型形参数列表可以在执行时指定,也可以在定义类模板中指定。下面看类型参数如何在执行时指定。

#include<bits/stdc++.h>
using namespace std;
template<class T1,class T2>
class MyTemplate{
	T1 t1;
	T2 t2;
	public:
	MyTemplate(T1 tt1,T2 tt2){
		t1=tt1,	t2=tt2;
	}
	void display(){
		cout<<t1<<" "<<t2<<endl;
	}
};
int main(void){
	int a=123;
	double b=3.1415;
	MyTemplate<int,double> mt(a,b);
	mt.display();
}

运行结果如下:

程序中的MyTemplate是一个模板类,它使用整型类型和双精度作为参数。

3.默认模板参数

默认模板参数就是在类模板定义时设置类型形式参数表中一个类型参数的默认值,该默认值是一个数据类型,有默认的数据类型参数后,在定义模板新类时就可以不进行指定。

4. 为具体类型的参数提供默认值

默认模版参数是类模板中由默认的数据类型作为参数,在模版定义时还可以为默认的数据类型声明变量,并且为变量赋值。

实例:为具体的参数提供默认值。

#include<bits/stdc++.h>
using namespace std;
template<class T1,class T2,int num=10>
class MyTemplate{
	T1 t1;
	T2 t2;
	public:
	MyTemplate(T1 tt1,T2 tt2){
		t1=tt1+num,t2=tt2+num;
	}
	void display(){
		cout<<t1<<" "<<t2<<endl;
	}
}; 
int main(void){
	int a=123;
	double b=3.1415;
	MyTemplate<int,double>mt1(a,b);
	MyTemplate<int,double,100>mt2(a,b);
	mt1.display();
	mt2.display();
}

运行结果如下:

5.有界数组模版

C++语言不能检查数组下标是否越界,如果下标会造成程序崩溃,程序员在编辑代码时很难找到下标越界错误,那么如何能让数组进行下标越界检测呢?答案是建立数组模版,在模版定义时对数组下标进行检查。

在模版中想要获取下标值,需要重载数组下标运算符“[ ]”,重载数组下标运算符后使用模板类实例化数组,就可以进行下标越界检测了。例如:

#include<cassert>
template<class T,int b>
class Array{
	T& operator[](int sub)
	{
		assert(sub>=0&&sub<b);
	}
};

程序中使用了assert来警告处理,当有下标越界情况发生时就弹出对话框警告,然后输出出现错误的代码位置。assert函数需要使用cassert头文件。

数组模版的应用示例如下:

#include<iostream>
#include<iomanip>
#include<cassert>
using namespace std;
class Date{
	int iMonth,iDay,iYear;
	char Format[128];
	public:
		Date(int m=0,int d=0,int y=0){
			iMonth=m;
			iDay=d;
			iYear=y;
		}
	    friend ostream& operator<<(ostream& os,const Date t){
	    	cout<<"Month:"<<t.iMonth<<endl;
	    	cout<<"Day:"<<t.iDay<<endl;
	    	cout<<"Year:"<<t.iYear<<endl;
	    	return os;
		}
		void display(){
			cout<<"Month:"<<iMonth;
			cout<<"Day:"<<iDay;
			cout<<"Year:"<<iYear;
			cout<<endl;
		}
};
template<class T,int b>
class Array{
	T elem[b];
	public:
		Array(){
		}
		T& operator[](int sub){
			assert(sub>=0&&sub<b);
			return elem[sub];
		}
};
int main(){
	Array<Date,3> dateArray;
	Date dt1(1,2,3);
	Date dt2(4,5,6);
	Date dt3(7,8,9);
	dateArray[0]=dt1;
	dateArray[1]=dt2;
	dateArray[2]=dt3;
	for(int i=0;i<3;i++){
		cout<<dateArray[i]<<endl;
	}
	Date dt4(10,11,12); 
	dateArray[3]=dt4;//越界 弹出警告 
	cout<<dateArray[3]<<endl;
}

?

程序能够及时发现dataArray已经越界,因为定义数组时指定数组长度为3,当数组下标为3时说明数组有4个元素,所以执行到dataArray[3]时,弹出错误警告。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:45:54  更:2022-03-31 23:47:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:12:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码