芜湖网站建设网站制作公司,谷歌推广外贸建站,wordpress导航列表,wordpress替换图片不显示相信大家都遇到过这么一种情况#xff0c;为了满足不同类型的需求#xff0c;我们要写多个功能相同#xff0c;参数类型不同的代码#xff0c;为此#xff0c;C引入了泛型编程这一概念#xff0c;而模板就是实现泛型编程的基础#xff0c;其实本质就是我们写一个类似”模…相信大家都遇到过这么一种情况为了满足不同类型的需求我们要写多个功能相同参数类型不同的代码为此C引入了泛型编程这一概念而模板就是实现泛型编程的基础其实本质就是我们写一个类似”模板”的代码当遇到不同类型需求时编辑器会按照我们写的模板自动生成对应类型的函数或类来防止相似的代码写很多遍的情况。
举个例子假设我们要写一个交换函数
//以前
void Swap(int x,int y){int tmpx;xy;ytmp;
}//....将类型换成我们需要的类型//现在
//函数模板
templateclass T
void Swap(T x,T y){T tmpx;xy;ytmp;
}
一、函数模板
函数模板代表了一个函数家族该函数模板与类型无关在使用时被参数化根据实参类型产生函数的特定类型版本
函数模板格式
templatetypename T1, typename T2,......,typename Tn 返回值类型 函数名(参数列表){}
注意这里class和typename都可以template的作用有点像typedef这里特别提醒一点每写一个函数模板或类模板都要单独写一个template
下面写一个加法函数模板
templateclass T
T Add(const T x, const T y)
{return x y;
}int main()
{cout Add(1, 2) endl;cout Add(1.1, 2.2) endl;return 0;
} 底层实现编辑器根据传的参数自动推导类型然后根据模板实例化函数然后运行得出答案
函数模板的实例化---显式实例化和隐式实例化
上面的代码就是隐式实例化即类型是编辑器自动推导的不是我们给的但是当参数的类型不同时( 如Add(1,1.2) )编辑器就会出现问题因为T可能是int也可能是double
这时我们有两种选择
1.强转将两个类型统一这样隐式实例化就能成立
2.显式实例化直接用Addint表明T的类型不用编辑器自动推动
注意如果有多个class T1,class T2,...,class Tn要根据顺序对应着写类型
代码如下
templateclass T
T Add(const T x, const T y)
{return x y;
}
int main()
{//强转cout Add(1, (int)1.2) endl;cout Add((double)1, 1.2) endl;//显示类型转换cout Addint(1, 1.2) endl;cout Adddouble(1,1.2) endl;return 0;
} 当函数模板和实体函数同时存在时如果不显示调用编辑器会默认调用已经存在的实体函数如下 函数模板的匹配原则
1. 一个非模板函数可以和一个同名的函数模板同时存在而且该函数模板还可以被实例化为这个非模板函数
2. 对于非模板函数和同名函数模板如果其他条件都相同在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数 那么将选择模板
3. 模板函数不允许自动类型转换但普通函数可以进行自动类型转换
二、类模板
类模板格式
templateclass T1, class T2, ..., class Tn class 类模板名 { // 类内成员定义 };
类模板的实例化
举个例子
templateclass T
class Vector
{
private:T* _a;size_t _size;size_t _capacity;
public:Vector(size_t n 4):_a(new T[n]),_size(0),_capacity(n){}//void push(T x);//...~Vector();
};templateclass T
VectorT::~Vector()//在类外写定义要加类型名,即类名,而在正常类中类型名类名
{delete[] _a;_size _capacity 0;
}int main()
{Vectorints1;//必须显式实例化Vectordoubles2;return 0;
}