第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院
7.1 函数模板 模板:函数和类模板。 函数模板简化重载。编译器遇到函数调用时,将根据实参类型和函数模板一起产生函数代码。 函数模板并不是真正意义上的函数,定义形式: template < 类型参数表 > 返回值类型 函数名 ( 形式参数表 ) { // 函数体 }
7.1.1 从函数重载到函数模板 函数重载是函数名相同,参数一定不完全相同,采用函数重载,要对每个函数分别写出相应的代码。例如:
int square ( int number ) { return number * number ; } float square ( float number ) 采用函数模板实现square: template < class T > T square ( T number )
template < class T > T square ( T number ) { 【例7.1】函数模板应用举例。 template < class T > T square ( T number ) { return number * number ; } int main ( ) { int userInt ; float userFloat ; cin >> userInt >> userFloat ; cout << "它们的平方分别是:" ; cout << square ( userInt ) << square ( userFloat ); return 0; 7-1.cpp
7.1.2 定义函数模板的方法 (1) 定义一个普通的函数 void swap ( int &var1 , int &var2 ) { 7.1.2 定义函数模板的方法 (1) 定义一个普通的函数 void swap ( int &var1 , int &var2 ) { int temp ; temp = var1 ; var1 = var2 ; var2 = temp ; } (2) 在函数开头加上template < class T >,将函数形参的类型和局部变量temp的类型int采用T替换。
7.1.3 在函数模板中使用多种类型 函数模板中可以使用多种通用类型,每个类型必须具有自己的参数: 7.1.3 在函数模板中使用多种类型 函数模板中可以使用多种通用类型,每个类型必须具有自己的参数: template < class T1 , class T2> void swap ( T1 &var1 , T2 &var2 ) { T1 temp ; temp = var1 ; var1 = ( T1 ) var2 ; var2 = ( T2 ) temp ; }
7.1.4 函数模板重载 template < class T > 7.1.4 函数模板重载 template < class T > T sum ( T valueOne , T valueTwo ) { return valueOne + valueTwo ; } T sum ( T valueOne , T valueTwo , T valueThree ) return valueOne + valueTwo + valueThree ; 调用形式:sum ( num1 , num2 ); sum ( num1 , num2 , num3); 形式之一
7.1.4 函数模板重载 float sum ( float valueOne , float valueTwo ) { 7.1.4 函数模板重载 float sum ( float valueOne , float valueTwo ) { return valueOne + valueTwo ; } template < class T > T sum ( T valueOne , T valueTwo , T valueThree ) return valueOne + valueTwo + valueThree ; 形式之二
7.2 类模板 类模板用于创建类属类和抽象数据类型,从而使程序员可以创建一般形式的类,而不必编写处理不同数据类型的类。 7.2 类模板 类模板用于创建类属类和抽象数据类型,从而使程序员可以创建一般形式的类,而不必编写处理不同数据类型的类。 类模板的定义和实现必须在同一个文件中,通常是头文件。编译器看到模板实现时才展开模板。 Example: Program 7-4.
template < class T > class FreewillArray { T *aptr; int arraySize; void memError(void); // allocation errors void subError(void); // out of range public: FreewillArray( ) { aptr = 0; arraySize = 0;} FreewillArray( int ); FreewillArray(const FreewillArray &); ~FreewillArray( ); int size( ) { return arraySize; } T &operator[ ](const int &); };
// Constructor for FreewillArray class. template < class T > FreewillArray <T>::FreewillArray( int s ) { arraySize = s; aptr = new T [s]; if (aptr == 0) memError(); for (int count = 0; count < arraySize; count++) *(aptr + count) = 0; }
// Copy Constructor for FreewillArray class. template <class T> FreewillArray<T>::FreewillArray ( const FreewillArray &obj ) { arraySize = obj.arraySize; aptr = new T [arraySize]; if (aptr == 0) memError(); for(int count = 0; count < arraySize; count++) *(aptr + count) = *(obj.aptr + count); }
// Destructor for FreewillArray class. template <class T> FreewillArray<T>::~FreewillArray( ) { if (arraySize > 0) delete [ ] aptr; } // memError function. void FreewillArray<T>::memError( ) { cout << "ERROR: allocate memory.\n"; exit(0);
// subError function. template <class T> void FreewillArray<T>::subError(void) { cout << "ERROR: Subscript out of range.\n"; exit(0); } // The argument is a subscript. T &FreewillArray<T>::operator[ ](const int &sub) { if (sub < 0 || sub > arraySize) subError(); return aptr[sub];
{ FreewillArray <int> intTable(10); void main( ) { FreewillArray <int> intTable(10); FreewillArray <float> floatTable(10); int x; for (x = 0; x < 10; x++) { intTable[x] = (x * 2); floatTable[x] = (x * 2.14); } cout << intTable[x] << " "; cout << endl; cout << floatTable[x] << " "; 7-4.cpp