1、泛型编程基础
泛型函数
#include "iostream"
using namespace std;
void swap(int &a, int &b)
{
int c ;
c = a;
a = b;
b = c;
}
void swap(float &a, float &b)
{
float c ;
c = a;
a = b;
b = c;
}
void main11()
{
int a = 1, b = 2;
swap(a, b);
float a1 = 1, b1 = 2;
swap(a1, b1);
system("pause");
}
//template关键字告诉c++编译器,现在开始泛型编程
//typename 告诉c++编译器,T为类型(T为类型,可以参数化,int float),你不要乱报错
//类型参数化。。。。。。。
template<typename T>
void swap2(T &a, T &b)
{
T c;
c = a;
a = b;
b = c;
}
void main()
{
//泛型编程的调用方式有两种
//自动类型推导
int x =1, y =2;
swap2(x, y);
printf("x:%d y:%d \n", x, y);
float x1= 1.0, y1 = 2.0;
//具体类型调用
swap2<float>(x1, y1);
printf("x1:%f y1:%f \n", x1, y1);
system("pause");
}
泛型类
#include <iostream>
using namespace std;
//定义一个类模板
template<typename T>
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<int>
{
public:
//BB(int a, int b) : AA(a)
BB(int a, int b) : AA<int>(a)
{
this->b = b;
}
private:
int b;
};
void main()
{
//要把类模板具体成类型后,才能定义变量
AA<int> a(10);
BB b1(1, 2);
system("pause");
}
/*
1 函数模板可以像普通函数一样被重载
2 C++编译器优先考虑普通函数
3 如果函数模板可以产生一个更好的匹配,那么选择模板
4 可以通过空模板实参列表的语法限定编译器只通过模板匹配
*/
/*
函数模板不允许自动类型转化
普通函数能够进行自动类型转换
*/
#include <iostream>
using namespace std;
int Max(int a, int b)
{
cout<<"int Max(int a, int b)"<<endl;
return a > b ? a : b;
}
template<typename T>
T Max(T a, T b)
{
cout<<"T Max(T a, T b)"<<endl;
return a > b ? a : b;
}
template<typename T>
T Max(T a, T b, T c)
{
cout<<"T Max(T a, T b, T c)"<<endl;
return Max(Max(a, b), c);
}
void main()
{
int a = 1;
int b = 2;
cout<<Max(a, b)<<endl; // 调用重载函数
cout<<Max<>(a, b)<<endl; // 这时候会强制调用泛型函数
cout<<Max(3.0, 4.0)<<endl;
cout<<Max(5.0, 6.0, 7.0)<<endl;
cout<<Max('a', 100)<<endl;
system("pause");
return ;
}3、函数模板加强,排序模板
#include "iostream"
using namespace std;
template<typename T>
void sortArray(T *a, int num)
{
int i =0, j = 0;
T tmp;
for (i=0; i<num; i++)
{
for (j=i; j<num; j++)
{
if (a[i] < a[j])
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
template<class T>
void printfArray(T *a, int num)
{
cout<<endl;
for (int i=0; i<num; i++)
{
cout<<a[i]<<" ";
}
}
void main()
{
int a[10] = {1, 3, 4, 5,2, 3,44, 6,3};
int num = sizeof(a)/sizeof(*a);
sortArray<int>(a, num);
printfArray<int>(a, num);
char buf[] = "163addeadfdsafdsaf";
int len = strlen(buf);
sortArray<char>(buf, len);
printfArray<char>(buf, len);
system("pause");
}4、模板实现本质是编译器会在编译的时候扫面模板函数记录下来,在用的时候会自动生成一个函数重载,其实和我们自己写函数重载时一样的,只不过是编译器为我们做了,可以看编译后的汇编源码,会发现没添加新的类型时候都会生成一个对应的重载函数
5、当友元函数碰上模板类的时候,如果将声明和实现分开写的情况下回出现编译不过,处理方法是声明和实现写到一起声明诚内联函数。没有别的处理办法
#include <iostream>
using namespace std;
template<class T>
class Complex
{
public:
Complex( T r =0, T i =0 );
Complex(T a) { Real = a ; Image = 0 ; }
void print() const;
friend Complex<T>operator+(Complex<T>&c1,Complex<T>&c2)
{
T r = c1.Real + c2.Real ; T i = c1.Image+c2.Image ;
return Complex<T>( r, i ) ;
}
//friend Complex operator- ( const Complex<T> & c1, const Complex<T> & c2 );
//friend Complex operator- ( const Complex<T> & c );
private:
T Real, Image ;
};
template<class T>
Complex<T>::Complex( T r, T i )
{
Real = r ; Image = i ;
}
/*
"class Complex<int> __cdecl operator+(class Complex<int> &,class Complex<int> &)" (??H@YA?AV?$Complex@H@@AAV0@0@Z),该符号在函数 _main 中被引用
1>E:\01-work\09-就业班0415\day16\泛型编程\Debug\泛型编程.exe : fatal error LNK1120: 1 个无法解析的外部命令
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
*/
// template<class T>
// Complex<T>operator+(Complex<T>&c1,Complex<T>&c2)
// {
// T r = c1.Real + c2.Real ; T i = c1.Image+c2.Image ;
// return Complex<T>( r, i ) ;
// }
template<typename T>
void Complex<T>::print()const
{
cout << '(' << Real << " , " << Image << ')' << endl;
}
void main61()
{
Complex<int>c1(1, 2);
Complex<int>c2(3, 4);
Complex<int>c3 = c1 + c2;
c3.print();
system("pause");
}6、当摸板类函数遇上static会为实际使用的每一种类添加一个静态成员
C++泛型编程实战
本文介绍了C++中的泛型编程基础知识,包括泛型函数和泛型类的定义与使用,探讨了泛型编程与函数重载之间的交互,并展示了如何利用泛型实现排序算法等实用功能。
519

被折叠的 条评论
为什么被折叠?



