c++ -- 函数模板和类模板

学习资源来源于中国MOOC,北大-面向对象程序设计


函数模板

  1. 定义: 函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能(百度定义
    一般形式:
template <class 类型参数1,class 类型参数2,……> 
返回值类型 模板名 (形参表) { 函数体 };

示例
在这里插入图片描述
在执行过程中,编译器自动生成 void Swap(int & ,int & )函数和//编译器自动生成 void Swap(float & ,float & )函数。

  1. 函数模板中可以有不止一个类型参数。
template <class T1, class T2> T2
print(T1 arg1, T2 arg2) {
	cout<< arg1 << " "<< arg2<<endl; 
	return arg2;
}

如求数组中最大元素的实现
在这里插入图片描述
3. 不通过参数实例化函数模板
在这里插入图片描述
直接在函数后加 <类型>即可。
4. 函数模板可以重载,只要它们的形参表或类型参数表不同即可。
在这里插入图片描述
5. 在有多个函数和函数模板名字相同的情况下,编译器如下处理一 条函数调用语句:

  1. 先找参数完全匹配的普通函数(非由模板实例化而得的函数)。
  2. 再找参数完全匹配的模板函数。
  3. 再找实参数经过自动类型转换后能够匹配的普通函数。
  4. 上面的都找不到,则报错。
    在这里插入图片描述
  1. 匹配模板函数时,不进行类型自动转换。
    在这里插入图片描述
    示例map模板
template<class T,class Pred> 
void Map(T s, T e, T x, Pred op) 
{ 
	for(; s != e; ++s,++x) { *x = op(*s);} 
}
int a[5] = {1,2,3,4,5}, b[5]; Map(a,a+5,b,Square); //实例化出以下函数: 
void Map(int * s, int * e, int * x, double ( *op)(double)) 
{ 
	for(; s != e; ++s,++x) 
	{ *x = op(*s);} 
}

其中double ( *op)(double))第一个double是返回参数类型,第二double是传入参数类型,op是函数指针。


类模板

为了多快好省地定义出一批相似的类,可以定义类模板,然后由类模 板生成不同的类。
类模板: 在定义类的时候,加上一个/多个类型参数。在使用类模板时,指定类型参数应该如何替换成具体类型,编译器据此生成相应的模板类。
一般形式

template <class 类型参数1,class 类型参数2,……> //类型参数表 
class 类模板名 {
成员函数和成员变量 
};

类模板里成员函数的写法:

 template <class 类型参数1,class 类型参数2,……> //类型参数表 
 返回值类型类模板名<类型参数名列表>::成员函数名(参数表) {
…… }

示例

#include<iostream>
using namespace std; 
template <class T1,class T2> 
class Pair {
public: 
	T1 key; //关键字 
	T2 value; //值
	Pair(T1 k,T2 v):key(k),value(v) { }; 
	bool operator < ( const Pair<T1,T2> & p) const;
};
template<class T1,class T2> 
bool Pair<T1,T2>::operator < ( const Pair<T1,T2> & p) const //Pair的成员函数 operator < 
{
	return key < p.key; 
}
int main() 
{
	Pair<string,int> student("Tom",19); //实例化出一个类 
	cout << student.key << " " << student.value; 
	return 0;
}

执行效果
在这里插入图片描述
编译器由类模板生成类的过程叫类模板的实例化。由类 模板实例化得到的类,叫模板类。

注意同一个类模板的两个模板类是不兼容的。
如下例子所示:

Pair<string,int> * p;
Pair<string,double> a; 
p = & a; //wrong

函数模版作为类模板成员

在这里插入图片描述
注意类模板的“<类型参数表>”中可以出现非类型参数。


类模板与派生

• 类模板从类模板派生
• 类模板从模板类派生
• 类模板从普通类派生
• 普通类从模板类派生
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


类模板与友元

• 函数、类、类的成员函数作为类模板的友元
• 函数模板作为类模板的友元
• 函数模板作为类的友元
• 类模板作为类模板的友元
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


类模板与静态 成员变量

在这里插入图片描述
在这里插入图片描述

发布了166 篇原创文章 · 获赞 45 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/104255151