类模板

本章内容为coursera课程C++程序设计中第七周的课件的整理

类模板
• 在定义类的时候给它一个/多个参数
• 这个/些参数表示不同的数据类型
在调用类模板时, 指定参数, 由编译系统根据参数提供的数据类型自动产生相应的模板类


C++的类模板的写法如下:

template <类型参数表>
class 类模板名
{
成员函数和成员变量
};
类型参数表的写法就是: class 类型参数1, class 类型参数2, …(typename也可)
类模板里的成员函数, 如在类模板外面定义时:

template <型参数表>
返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)
{
……
}

#include <iostream>  
using namespace std ;  
template <class T>  
class Base  
{  
public :      
    T a ;  
    Base(T b)  
    {  
        a = b ;      
    }     
    T getA(){ return a ;} //类内定义   
    void setA(T c);  
};  
  
template <class T>   //模板在类外的定义   
void  Base<T>::setA(T c)  
{  
    a = c ;  
}  
  
int main(void)  
{  
    Base <int>b(4);  
    cout<<b.getA()<<endl;   
  
    Base <double> bc(4);  
    bc.setA(4.3);  
    cout<<bc.getA()<<endl;   
    system("pause");   
    return 0 ;      
}  

用类模板定义对象的写法如下: 类模板名 <真实类型参数表> 对象名(构造函数实际参数表);
如果类模板有无参构造函数, 那么也可以只写: 类模板名 <真实类型参数表> 对象名;

//Pair类模板:
template <class T1, class T2>
class Pair{
public:
T1 key; //关键字
T2 value; //值
Pair(T1 k,T2 v):key(k),value(v) { };
bool operator < (const Pair<T1,T2> & p) const;
};
template<class T1,class T2>
bool Pair<T1,T2>::operator<( const Pair<T1, T2> & p) const
//Pair的成员函数 operator <
{ return key < p.key; } 
//Pair类模板的使用:
int main()
{
Pair<string, int> student("Tom",19);
//实例化出一个类 Pair<string, int>
cout << student.key << " " << student.value;
return 0;
}
输出结果:
Tom 19

使用类模板声明对象
编译器由类模板生成类的 过程类模板的实例化
• 编译器自动用 具体的数据类型,替换类模板中的 类型参数, 生成模板类的代码
由类模板实例化得到的 模板类
• 为类型参数指定的数据类型不同, 得到的模板类不同


同一个类模板的两个模板类是不兼容的

Pair<string, int> * p;
Pair<string, double> a;
p = & a; //wrong


函数模版作为类模板成员

#include <iostream>
using namespace std;
template <class T>
class A{
public:
template<class T2>
void Func(T2 t) { cout << t; } //成员函数模板
};
int main(){
A<int> a;
a.Func('K'); //成员函数模板 Func被实例化
return 0;
}
程序输出:
K

若函数模板改为:
template <class T>
void Func(T t){cout<<t}
将报错 “declaration of ‘class T’shadows template parm ‘class T’ ”)

类模板与非类型参数
类模板的参数声明中可以包括非类型参数
template <class T, int elementsNumber>
• 非类型参数: 用来说明类模板中的属性
• 类型参数: 用来说明类模板中的属性类型, 成员操作的参数类型和返回值类型

//类模板的 “<类型参数表>” 中可以出现非类型参数:
template <class T, int size>
class CArray{
T array[size];
public:
void Print( )
{
for(int i = 0; i < size; ++i)
cout << array[i] << endl;
}
};

CArray<double, 40> a2;
CArray<int, 50> a3;
注意:
CArray<int,40>和CArray<int,50>完全是两个类,这两个类的对象之间不能互相赋值

类模板与继承

1.类模板派生出类模板
2.模板类 (即类模板中类型/非类型参数实例化后的类)派生出类模板
3.普通类派生出类模板
4.模板类派生出普通类

(1) 类模板从类模板派生

template <class T1, class T2>
class A {
T1 v1; T2 v2;
};
template <class T1, class T2>
class B:public A<T2,T1> {
T1 v3; T2 v4;
};
16
template <class T>
class C:public B<T,T>{
T v5;
};
int main(){
B<int, double> obj1;
C<int> obj2;
return 0;
}
(2) 类模板从模板类派生
template <class T1, class T2>
class A { T1 v1; T2 v2; };
template <class T>
class B:public A<int, double> { T v; };
int main() { B<char> obj1; return 0; }
自动生成两个模板类:A<int, double>和B<char>

(3) 类模板从普通类派生

class A { int v1; };
template <class T>
class B:public A { T v; };
int main() {
B<char> obj1;
return 0;
}

(4)普通类从模板类派生

template <class T>
class A { T v1; int n; };
class B:public A<int> { double v; };
int main() {
B obj1;
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值