1、模板 :分为类模板和函数模板;最大的特点是不编译,所以一般放在头文件中,使用时加个include;
2、模板的意义: 可以对类型进行参数化;
一个函数模板
template<typename T>
/*模板参数列表,可以有多个,但至少要有一个;T就叫做模板类型参数,
我们也可以在里面在定义一个int a,这个就是模板非类型参数
*/
bool pri(T a,T b)
{
cout<<"pri"<<endl;
return a>b;
}
此时这个模板并不能比较两个字符串,所以我们要为字符串写一个模板的特例化,并且一般来讲,涉及字符串的模板都需要写出字符串的特例化;
template <>//注意模板特例化这里不写参数
bool pri(char*a,char*b)
{
cout<<"pri(char*)"<<endl;
return strcmp(a,b);
}
关于特例化,分为完全特例化和部分特例化;如上所写的就是完全特例化,参数只能为字符串类型,,但如果是int*,float*呐???此时我们就需要再写一个部分特例化
bool pri(T*a,T*b)
{
cout<<"pri(*)"<<endl;
return true;;
}
int main()
{
pri(10,20);
// 函数的调用点 =》 根据指定类型函数模板进行实例化 =》 模板函数
pri("aa","bb");//调用时,编译器会参数推演,所以这个调用特例化模板;
int arr[]={1,2,3};
int brr[]={4,5,6};
pri<int>(arr,brr);
return 0;
}
一个类模板:链表的模板
template<typename T>
class Link
{
public:
Link()//构造
{
cout<<"Link()"<<endl;
}
~Link()//析构
{
cout<<"~Link()"<<endl;
}
Link(const T&src)//拷贝构造
{
cout<<"Link(src)"<<endl;
}
Link&operator=(const T&src)//赋值
{
cout<<"operator()"<<endl;
}
void insertHead(const T &val)//头插法
{
cout<<"inserthead"<,endl;
}
template<typename T>
void insertHead(const T &val)//头插法
{
cout<<"inserthead"<<endl;
}
template<>
void insertHead<char*>(char* const & val)//头插法 特例化版本
{
cout<<"inserthead(char*)"<<endl;
}private:
struct Node
{
//零构造 零初始化
//零构造 既date=T类型的0;
//比如 T==int 那么data=0;T=char 那么date等于'\0'
Node(T data=T(),S data1=S()) :mdata1(data), mpnext(NULL){}
T mdata1;
Node *mpnext;
};
Node *mphead;
};
int main()
{
Link<int>s1;//函数的调用点
//函数模板在函数的调用点,通过制定类型
int a=10;
char*b="guo";
s1.insertHead(a);
Link<char*>s2;
s2.insertHead(b);
return 0;
}