一、模板
函数模板 和 类模板
不限于类型的即为模板
二、函数模板
以Max函数为例:
int Max(int a, int b)
{
return a > b ? a : b;
}
1、函数模板:
template<class T,class T,...> //函数模板--经过类型参数化--->模板函数
T Max(T a, T b,...)//将通用数据类型全部改成T
{
return a > b ? a : b;
}
template
:模板关键字
<class T,class T,...>
:参数列表
class T
:类型参数表
2、模板简单使用
对于以下代码:
这三个函数,除了类型不一样,内部的实际的执行是一样的,为实实在在的,有明确数据类型的函数。
类比于制作巧克力的摸具,其做出来的巧克力大小型状是一样的,只是巧克力的口味等不相同。
//函数名相同,但函数返回值、参数不同,构成重载
int Max(int a, int b)
{
return a > b ? a : b;
}
double Max(double a, double b)
{
return a > b ? a : b;
}
char Max(char a, char b)
{
return a > b ? a : b;
}
void main()
{
cout << Max(4, 6) << endl; //类型参数化 int
cout << Max(3.4, 1.2) << endl; //double
cout << Max('a', '1') << endl; //char
}
运行结果:
模板使用:
template<class T> //函数模板--经过类型参数化--->模板函数
T Max(T a, T b)
{
return a > b ? a : b;
}
void main()
{
cout << Max(4, 6) << endl; //类型参数化 int
cout << Max(3.4, 1.2) << endl; //double
cout << Max('a', '1') << endl; //char
}
模板特化 – 具体化 --char*
template<class T> //函数模板--经过类型参数化--->模板函数
T Max(T a, T b)
{
return a > b ? a : b;
}
//模板的特化--具体化
template<>
const char* Max(const char* a, const char* b)
{
cout << "const char* Max" << endl;//检验是否调用
return strcmp(a, b) > 0 ? a : b;
}
void main()
{
cout << Max(4, 6) << endl; //类型参数化 int
cout << Max(3.4, 1.2) << endl; //double
cout << Max('a', '1') << endl; //char
cout << Max("333", "555") << endl; //const char*
}
运行结果:
函数模板–sort函数
对于不同类型的数组都可进行排序
void main()
{
int a[] = {1,5,6,9,12,4,7,5,1};
int n = sizeof(a)/sizeof(a[0]);
sort(a,a+n);//将a到a+n从小到大进行排序-- 模板
for(int i = 0;i < n;i++)
cout<< a[i]<<" ";
cout <<endl;
char b[] = {'1','d','h','8','9','i'};
n = sizeof(b)/sizeof(b[0]);
sort(b,b+n);
for(int i = 0;i < n;i++)
cout<< b[i]<<" ";
cout <<endl;
double c[] = {10.2,15.0,61.2,22.3,2.3,2.9,2.1};
n = sizeof(c)/sizeof(c[0]);
sort(c,c+n);
for(int i = 0;i < n;i++)
cout<< c[i]<<" ";
cout <<endl;
}
运行结果:
三、类模板
以A类为例:
class A
{
public:
A(int i) :m_i(i) {}
void print()
{
cout << "m_i = " << m_i << endl;
}
private:
int m_i;
};
void main()
{
A a(4);
a.print();
}
类模板的使用
template<class T>
class A
{
public:
A(T i) :m_i(i) {}
void print()
{
cout << "m_i = " << m_i << endl;
}
private:
T m_i;
};
//vector list stack queue 都需要大量使用模板
template<>//模板特化 -- 具体化 --char*
class A<const char*>
{
public:
A(const char* i)
{
cout << "A const char*" << endl;
m_i = new char[strlen(i) + 1];
strcpy_s(m_i, strlen(i) + 1, i);
}
void print()
{
cout << "A::m_i = " << m_i << endl;
}
~A()
{
delete[]m_i;
}
private:
char* m_i;
};
void main()
{
A<int> a(4); //将int当成参数传递给模板中的T-->模板类
a.print();
A<char> b('6');
b.print();
A<double> c(3.5);
c.print();
A<const char*> d("helloworld");
d.print();
}
运行结果:
4、sort函数内部的各种调用
sort(a,a+n,greater<int>());//从小到大排序
//其中的greater就显然是类模板;
bool great(char a,char b)
{
return a > b;
}
class Great
{
public:
bool operator()(char a,char b)
{
return a > b;
}
};
template<class T>
class GREAT
{
public:
bool operator()(T a,T b)
{
return a > b;
}
};
void main()
{
int a[] = {1,5,6,9,12,4,7,5,1};
int n = sizeof(a)/sizeof(a[0]);
//sort(a,a+n);//将a到a+n从小到大进行排序-- 模板
//sort(a,a+n,greater<int>());//类模板的调用,从大到小
//sort(a,a+n,great);//传函数名,函数指针的应用
//sort(a,a+n,Great());//调用Great类中的()重载,
sort(a,a+n,Great<char>());//再函数模板中用了类模板
for(int i = 0;i < n;i++)
cout<< a[i]<<" ";
cout <<endl;
}