模板的概念
- 模板指C++能够将数据类型作为一个可变化的数据类型形参进行定义的功能。
- 模板就是将类型参数化
函数模板
目录
int、float、char ----> class ELEMENT_TYPE
- 在函数声明中包含有参数化数据类型的函数
- 函数模板表示的是对不同数据类型数据进行相同处理的一类函数。
template <class T1, class T2, …...>
返回值类型 函数名(形式参数表)
{ 函数体 }
调用函数模板
常见的模板设计错误
重载函数模板
函数调用的匹配规则
引入函数模板后,编译程序根据函数调用的实际参数类型决定调用函数的哪一个版本的匹配规则: 1)如果函数的调用的实际参数类型正好与某一函数的参数类型匹配,则调用该函数;否则
2)如果能从同名的函数模板实例化一个函数实例,而函数调用的实际参数类型正好与该函数的参数类型匹配 ,则调用该实例化的函数;否则
3)对函数调用的实际参数作隐式类型转换后与非模板函数再作匹配,找到匹配的函数则调用它;否则
4)提示语法错误。
函数模板的二义性
- 定义重载函数时,要注意避免产生预期或非预期的二义性。
自定义类的对象调用函数模板
举例:
class CComplex
{ private:
double real, image;
public:
CComplex() { real = 0.0; image = 0.0; }
CComplex(double a, double b){ real = a; image = b; }
void print() const;
const CComplex& operator= (const CComplex &r_c);
bool operator> (const CComplex &r_c) const;
};
void CComplex::print() const
{ if (image < 0)
cout << real << image << "i";
else if (image > 0)
cout << real << "+"<< image <<"i";
else
cout << real;
}
const CComplex& CComplex::operator= (const CComplex &r_c)
{ real = r_c.real;
image = r_c.image;
return *this;
}
bool CComplex::operator> (const CComplex &r_c) const
{ if(real > r_c.real && image > r_c.image)
return true;
else
return false; }
template <class Type>
Type &max(Type &r_n1, Type &r_n2)
{
return (r_n1 > r_n2) ? r_n1 : r_n2;
}
void main()
{ char char1 = 'a';
char char2 = 'b';
float float1 = -123.45f;
float float2 = 42.1f;
CComplex c1(3.0, -2.3), c2(6.3, -1.2), c;
cout << "max(" << char1 << "," << char2 << ")=" << max(char1, char2)<< endl;
cout << "max(" << float1 << "," << float2 << ")=" << max(float1, float2) << endl;
c = max(c1, c2);
cout << "max(";
c1.print();
cout << ",";
c2.print();
cout << ")=";
c.print();
cout << endl; }
类模板
整型数组类:
class IntegerList{
protected:
int * vector;
int size;
public:
IntegerList (int length) { //构造函数
vector=new int[length];
size=length;
}
~IntegerList( ) { delete [ ] vector; } //析构函数
int& operator[ ](int index) {
return vector[index]; }
};
浮点型数组类:
class FloatList{
protected:
float * vector;
int size;
public:
FloatList (int length) { //构造函数
vector=new float[length];
size=length;
}
~FloatList( ) { delete [ ] vector; } //析构函数
float& operator[ ](int index) {
return vector[index]; }
};
字符型数组类:
class CharList{
protected:
char * vector;
int size;
public:
CharList (int length) { //构造函数
vector=new char[length];
size=length;
}
~CharList( ) { delete [ ] vector; } //析构函数
char& operator[ ](int index) {
return vector[index]; }
};
int、float、char ----> class ELEMENT_TYPE
定义一个数组类模板-------List
template<class ELEMENT_TYPE>
class List{
protected:
ELENENT_TYPE* vector;
int size;
public:
List (int length) { //构造函数
vector=new ELEMENT_TYPE[length];
size=length;
}
~List( ) { delete [ ] vector; } //析构函数
ELEMENT_TYPE& operator[ ](int index) {
return vector[index]; }
};
类模板的含义
在设计一个类时,将数据类型作为类的参数, 作为参数的类型可以是C++语言提供的基本数据类型和复合数据类型,也可以是程序自定义的类类型。
类模板的定义
例:定义一个数组类模板List
template<class ELEMENT_TYPE>
class List{
protected:
ELEMENT_TYPE* vector;
int size;
public:
List (int length); //构造函数
~List( ) { delete [ ] vector; } //析构函数
ELEMENT_TYPE& operator[ ](int index);
};
template<class ELEMENT_TYPE>
List< ELEMENT_TYPE >::List (int length)
{
vector=new ELEMENT_TYPE[length];
size=length;
for(int i=0;i<size;i++)
vector[i]=i;
}
template<class ELEMENT_TYPE>
ELEMENT_TYPE& List< ELEMENT_TYPE >::operator[](int index)
{
return vector[index];
}
//注意:类名为 List<ELEMENT_TYPE>
注意:
- 用template 引出模板形式参数;
- 类定义中数据类型使用模板形式参数。
- 这种形式的类不能直接用于创建对象实例。为什么?)
- 在类定义之外实现成员函数时,必须逐一指明模板参数,否则产生语法错误。
类模板实例化
- 类模板中的模板参数尚未确定,故不能直接利用类模板创建对象。
- 类模板实例化:用某一个具体的数据类型替代类模板中的模板参数。
- 类模板的一个实例称为类模板对象——模板类。
【类模板是抽象的类,而模板类是实例化了的具体类。】
- 利用类创建实例的过程也称为实例化,但这是与类模板实例化不同的过程(它不必给出实际模板参数表)。
- 类模板的实例化创建的结果是一种类型,而类的实例化创建的是一个对象。
类模板实例化的一般形式
举例:
#include <iostream>
using namespace std;
template<class TYPE1, class TYPE2> //带两个模板形参
class MUTI_PARA
{public:
MUTI_PARA(TYPE1 x, TYPE2 y)
{ first=x; second=y; }
void show()
{ cout<<first<< '\t'<<second<<endl; }
private:
TYPE1 first; TYPE2 second;
};
int main(){
MUTI_PARA<int, double> obj1(2, 3.14);
MUTI_PARA<char*, char> obj2("Are you sure?", 'Y');
obj1.show( );
obj2.show( );
return 1;
}
类模板的继承和派生