一.泛类型编程的语法基础
1.template或template:T为类型,可以定义变量,类似于int ,float.
2.template关键字告诉编译器,现在要开始进行泛类型编程
3.举个小例子用swap实现交换
template
void Swap(T &a, T &b)
{
T c;
c = a;
a = b;
b = c;
}
void main()
{
int x1 = 1, y1 = 2;
Swap(x1, y1);//自动类型推导
printf("x1:%d,x2:%d\n", x1, y1);
float x2 = 2, y2 = 3;
Swap(x2, y2);//具体类型调用
printf("x2:%f,y2:%f", x2, y2);
system("pause");
}
从运行结果可以看出来,泛类型编程有两种调用方法:
(1)自动类型推导,编译器会根据你所定义的变量类型推导出调用的类型
(2)具体类型调用,自定义什么类型,编译器就执行哪种类型
****刚好这块用到了swap引用传递,我想起来昨天在牛客上刷题时遇到的一个小知识点,比较容易出错,在这里我作为小知识点加进去:
在这里我把值传递和引用传递做一个小比较:
1. 在函数定义格式上有不同: 值传递在定义处是:Exchg1(int x, int y); 引用传递在这义处是:Exchg1(int &x, int &y); 2. 调用时有相同的格式: 值传递:Exchg1(a,b); 引用传递:Exchg3(a,b); 3. 功能上是不同的: 值传递的函数里操作的不是a,b变量本身,只是将a,b值赋给了x,y函数里操作的只是x,y变量而不是a,b,显示a,b的值不会被Exchg1函数所修改。 引用传递Exchg3(a,b)函数里是用a,b分别代替了x,y。函数里操作的是a,b。
|
二.函数模板
1.函数模板可以像普通函数一样被重载 2.c++编译器优先考虑普通函数 3.如果函数模板可以产生一个更好的匹配,那么选择模板 4.可以通过空模板实参列表的语法限定编译器只通过模板匹配 5.函数模板不允许自动类型转换,而普通函数能够进行自动类型转换,在下面的代码中我会举例说明
|
函数模板的深入理解
——编译器并不是把函数模板处理成能够处理任意类型的函数 —— 编译器从函数模板通过具体类型产生不同的函数 ——编译器会对函数模板进行两次编译 ——在声明的地方对模板代码本身进行编译 ——在调用的地方对参数替换后的代码进行编译 |
1.下面举代码例子说明(对数组和字符串进行排序打印)
template
void sortArray(T *a, int num)
{
int i = 0;
int j = 0;
T tmp;
for (i = 0; i < num; i++)
{
for (j = i + 1; j < num; j++)
{
if (a[i]>a[j])
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
template
void printfArray(T *a, int num)
{
int i = 0;
int j = 0;
for (i = 0; i < num; i++)
{
cout << a[i] <<" " ;
}
}
void main()
{
int a[10] = { 3, 2, 6, 5, 7, 8, 0 };
int num = sizeof(a) / sizeof(*a);
sortArray(a, num);
printfArray(a, num);//此处就是泛型编程的第二种用法,具体类型调用
cout << endl;
char buf[] = "2378623jduhydujmasdn";
int len = strlen(buf);
sortArray(buf, len);
printfArray(buf, len);
system("pause");
注意:第一个运行结果前面之所以有四个零,是因为在初始化数组时,定义数组个数不够时,编译器默认后面的数字为0.
2.再举一个当函数模板遇上函数重载的例子
int Max(int a, int b)//普通函数 { cout<<"int Max(int a, int b)"<return a > b ? a : b; }
template//函数模板 T Max(T a, T b) { cout<<"T Max(T a, T b)"<return a > b ? a : b; }
template T Max(T a, T b, T c)//函数重载 { cout<<"T Max(T a, T b, T c)"<return Max(Max(a, b), c); }
void main() { int a = 1; int b = 2;
cout<cout<(a, b)<
cout<
cout<
cout<system("pause"); return ; }
|
注意:在执行cout<,然后再是两次T Max,是因为在定义函数时,返回的是 Max(Max(a,b),c);先进入该函数,然后进行啊,a,b比较函数,比较结果再与c进行比较
三.类模板
我会用两个小例子进行说明
1.
template class AA { public: AA(T a) { this->a = a; } void setA(T a) { this->a = a; } T getA() { return this->a; } protected: private: T a; };
class BB : public AA { public: //BB(int a, int b) : AA(a) BB(int a, int b) : AA(a) { this->b = b; }
private: int b; };
void main() { //要把类模板具体成类型后,才能定义变量 AA a(10);
BB b1(1, 2); system("pause"); } |
由于没有把BB定义成具体类型,因此会报错
2.
template class Complex { public: Complex(T r = 0, T i = 0){ Real = r; Image = i; } Complex(T a){ Real = a; Image = 0; } void print() const{ cout << '(' << Real << "," << Image << ')' << endl; } friend Complexoperator+(Complex&c1, Complex&c2) { T r = c1.Real + c2.Real; T i = c1.Image + c2.Image; return Complex(r, i); } private: T Real, Image; }; void main() { Complexc1(1, 2); Complexc2(3, 4); Complexc3= c1 + c2; c3.print(); system("pause");
} |
以上就是我总结关于模板的用法,希望能对你们有所帮助。