C++模板
模板定义:模板是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了真正的代码可重用性。
模板分类:函数模板和类模板。
函数模板针对参数类型不同的函数;类模板仅针对数据成员和成员函数类型不同的类。
使用模板目的:让程序员编写与类型无关的代码。
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,如不能在main函数中声明或定义一个模板。
一、模板函数
1.一般模板函数
形式:template < typename T>(通用函数定义)或者template < class T>
template返回类型 函数名(参数列表) { 函数体 }
其中template和class是关键字,class可以用typename 关键字代替,在这里typename 和class没区别,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。
2.特化模板函数
函数模板的特化:当函数模板需要对某些类型进行特别处理,称为函数模板的特化。
//泛型版本 templateint compare(const T &v1, const T &v2) { if(v1 < v2) return -1; if(v2 > v1) return 1; return 0; }
对于该函数模板,当实参为两个char指针时,比较的是指针的大小,而不是指针指向内容的大小,此时就需要为该函数模板定义一个特化版本,即特殊处理的版本:
//为实参类型 const char * 提供特化版本 template <> int compare(const char * const &v1, const char * const &v2) { return strcmp(v1, v2); }
a: template <> //空模板形参表
b: compare
//特化版本 (int *) template <> int compare(const int * const &v1, const int * const &v2)//v1 和 v2 是指向const 整形变量的const引用; { if(*v1 < *v2) return -1;//像指针一样操作,可以理解v1,v2就是指针,因为它是指针的引用; if(*v2 > *v1) return 1; }
二、模板类Queue或Stack
1.模板类(Queue,Stack)
形式:template< class 形参名, class 形参名, ……> class 类名 {…};
templateclass 类名{ ... };
类模板和函数模板都是以template开始后接模板形参列表组成,模板形参不能为空,一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。
2.成员模板函数
形式:template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体}
比如有两个模板形参T1,T2的类A中含有一个void h()函数,则定义该函数的语法为:
templatevoid A ::h(){}。
3.模板特化:模板函数特化、模板成员函数特化、模板类特化
类模板:
测试代码如下: #includeusing namespace std; template class Test{ public: Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"< //全特化,由于是全特化,参数都指定了,参数列表故为空。 class Test { public: Test(int i,char j):a(i),b(j){cout<<"全特化"< //由于只指定了一部分参数,剩下的未指定的需在参数列表中,否则报错。 class Test { public: Test(char i,T2 j):a(j),b(j){cout<<"个数偏特化"< //这是范围上的偏特化 class Test { public: Test(T1* i,T2* j):a(i),b(j){cout<<"指针偏特化"< //同理这也是范围上的偏特化 class Test { public: Test(T1 i,T2 j):a(i),b(j){cout<<"const偏特化"< t1(0.1,0.2); Test t2(1,'A'); Test t3('A',true); Test t4(&a,&a); Test t5(1,2); return 0; }
运行截图
函数模板:
而对于函数模板,却只有全特化,不能偏特化:
#includeusing namespace std; //模板函数 template void fun(T1 a,T2 b){ cout<<"模板函数"< void fun(int a,char b){ cout<<"全特化"< 运行截图:
三、模板类AutoPtr
auto_ptr是C++标准库中为了解决资源泄漏的问题提供的一个智能指针类模板(注意:这只是一种简单的智能指针)
auto_ptr的实现原理其实就是RAII(Resource Application Immediately Initialize),在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。auto_ptr是一个模板类,定义如下:
templateclass auto_ptr {...}; 1.构造函数与析构函数
构造函数:int* p = new int(33); auto_ptrapi(p); 直接构造智能指针
auto_ptr< int > api( new int( 33 ) );2.拷贝构造函数
利用已经存在的智能指针来构造新的智能指针auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) ); auto_ptr< string > pstr_auto2( pstr_auto ); //利用pstr_auto来构造pstr_auto23.对于auto_ptr使用总结
auto_ptr存储的指针应该为NULL或者指向动态分配的内存块。
auto_ptr存储的指针应该指向单一物件(是new出来的,而不是new[]出来的)。



