泛型编程:使用模板,编写跟类型无关的代码
模板的引入:写一些函数和类的时候,针对不同类型需要写很多重复的代码
模板原理:编译器根据调用函数模板和类模板的类型,实例化出对应的函数和类
#include <iostream>
using namespace std;
//void Swap(int& a, int& b)
//{
// int tmp = a;
// a = b;
// b = tmp;
//}
//void Swap(double& c, double& d)
//{
// double tmp = c;
// c = d;
// d = tmp;
//}
//void Swap(char& e, char& f)
//{
// char tmp = e;
// e = f;
// f = tmp;
//}
template<class T>
//template<typename T>
void Swap(T& x1, T& x2)
{
T x = x1;
x1 = x2;
x2 = x;
}
//下面调用的不是同一个函数,调用的是函数模板实例化生成的对应类型的函数
int main()
{
int a = 1, b = 2;
Swap(a, b);
double c = 1.1, d = 2.1;
Swap(c, d);
char e = 'a', f = 'b';
Swap(e, f);
return 0;
}
1.函数模板
template<class T>
void swap(T& a,T& b){...}
2.类模板
template<class T>
class stack
{
private:
T* _a;
size_t _size;
size_t _capacity;
}
#include <iostream>
#include <assert.h>
using namespace std;
---c
//template<class T>
//class SeqList
//{
//};
---cpp
//vector 管理动态增长的数组
template<class T>
class vector
{
public:
vector()
:_a(nullptr)
,_size(0)
,_capacity(0)
{}
vector(size_t n)
:_a(new T[n])
,_size(0)
,_capacity(n)
{}
~vector()
{
delete[] _a;
_a = nullptr;
_size = _caacity = 0;
}
//void push_back(T x);//如果vectop<int> v的类型不是int,例如date之类的,传参方式是传值类型,进行了拷贝构造
//类里面声明
void push_back(const T& x);//用引用,减少拷贝,提高效率
void pop_back();
size_t size()
{
return _size;
}
//T operator[](size_t i)
//{
// assert(i < _size);
// return _a[i];
// }
// 对应 v[i] *= 2; 出错,左操作数必须为左值,即v[i]不能被修改
//改正后
T& operator[](size_t i)
{
assert(i < _size);
return _a[i];
}
private:
T* _a;
size_t _size;
size_t _capacity;
};
//类外面定义
template<class T>
void vector <T>::push_back(const T& x)
{
//如果空间不足,则需要增容
if(_size == _capacity)
{
size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
T* tmp = new T[newcapacity];
if(_a)
{
memcpy(tmp,_a,sizeof(T)*_size);
delete[] _a;
}
_a = tmp;
_capacity = newcapacity;
}
_a[_size] = x;
++_size;
}
template<class T>
void vector <T>::pop_back()
{
assert(_size > 0);
--_size;
}
int main()
{
vectop<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for(size_t i = 0; i< v.size;++i)
{
// v[i] *= 2; 出错,左操作数必须为左值,即v[i]不能被修改
v[i] *= 2;
}
for(size_t i = 0; i< v.size;++i)
{
cout << v[i] << "";
}
cout << end1;
return 0;
}
vector 是类名,vector 是类型
显式和隐式实例化
template<class T>
T Add(const T& left,const T& right)
{
return left + right;
}
int main()
{
int a1 = 10,a2 = 20;
double d1 = 10.0,d2 =20.0;
//隐式实例化(T的类型是编译器自己推导的)
Add(a1,a2);
Add(d1,d2);
//Add(a1,d1);出错
Add(a1,(int)d1);
//显示实例化(指定T的类型)
Add<int>(a1,d1);
}
函数与模板函数同时存在时的调用方式
//专门处理int的加法函数
int Add(int left,int right)
{
return left + right;
}
//通用加法函数
template<class T>
T Add( T left,T right)
{
return left + right;
}
void main()
{
Add(1,2);//与非模板函数匹配
Add<int>(1,2);//与模板函数匹配
}