一篇文章读懂类模板

文章摘自: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]时,弹出错误警告。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值