C++ 模板

模板

1 定义:

模板把函数或类要处理的数据类型参数化,表现为参数的多态性。 在面向对象技术中,这种机制称为类属

模板用于表达逻辑结构相同,但具体数据元素类型不同的数据对象的通用行为。

模板说明:
模板说明的作用是声明模板中使用的类属参数。

模板说明的形式为: template<class T1,class T2,…,class Tn>

采用关键字template开始,之后是采用“<>”相括的形式类型参数(类属参数)表,每一个参数前都加有关键字class,Ti是用户定义的标识符,前缀class指定它们为类属参数,即可以实例化为任何内部类型或用户自定义类型。

2 函数模板

2.1 函数模板与模板函数

一般函数是对相同类型数据对象操作的抽象。函数模板是对相同逻辑结构(不同数据类型)数据对象操作的抽象,是生成不同类型参数重载函数的模板。

函数模板=模板说明+函数定义

例:求两个数中的最大值

//定义函数模板,先说明模板的类属参数T,然后是函数的实现定义
template<typename T>
T Max<const T a,const T b>
{return a>b?a:b;}
//函数
#include"Max.h"
#include<ioistream.h>
   void main(){
       int j,k;
       cin>>j>>k;
       cout<<Max(j,k)<<endl;
       doubel x,y;
       cin>>x>>y;
       cout<<Max(x,y)<<endl;
}

分析:函数模板Max不是真正的函数,仅仅是一个提供生成不同类型参数重载函数版本的“模板”而已。

第一步:编译阶段,编译器根据调用语句中实际参数的类型对函数模板实例化,生成可运行的函数即:

T Max<const T a,const T b>
{return a>b?a:b;}

将T替换为int,double

int Max<const int a,const int b>
{return a>b?a:b;}
double Max<const double a,const double b>
{return a>b?a:b;}

函数模板与模板函数关系:这些重载函数,通过函数模板按照实际类型生成,成为模板函数,这个过程成为实例化,即:函数模板实例化后成为了模板函数。

第二步:运行阶段,实参与形参进行结合,之心对应的模板函数。

定义冒泡排序的函数模板

template<typename T>
void SortBubble(T *a,int size)
{
   int i,work;
   T temp;
  for(int i=0;i<size;i++){
​        work=1;for(int j=i+1;j<size;j++){if(a[i]->data>a[j]->data){
​              temp=a[i]->data;
​               a[i]->data=a[j]->data;
​                a[j]->data=temp; 
​               work=0;}if(work) break;}}
}

2.2 重载函数模板

2.2.1 函数模板的重载

重载函数模板便于定义类属参数,或者函数参数的类型、个数不相同所进行的类似操作。

Max函数模板可以重载为求数组最大元素的函数模板。

T Max(const T *a,int n)
{
   T temp;
   int i=0;
   temp=a[0];
   for(i;i<n;i++){
      if(a[i]>a[i+1])
      {
​        temp=a[i];
      }
   }
  return temp;
}

与Max同名,是重载的函数模板。

2.2.2 用普通函数重载模板

前言: 函数模板实例化时,实际参数类型替换类属参数,虽然这种参数具有类型检查的功能,却没有普通传值参数的类型转换机制。

对于函数模板

T Max<const T a,const T b>
{return a>b?a:b;}

进行调用时,对应的两个实际参数必须类型相同,否则将出现语法错误。

int k,char c;//与Max(int ,char)无法匹配

问题:typename不知道二者之间可以进行隐式类型转换

解决:使用非模板函数进行重载

int Max(const int k,const char c) 
//可以**隐式的进行类型转换**
{return k>c? a:b;}

存在隐患:重载函数会导致函数调用的二义性

如果重载函数为**int Max(int,int)则会与T Max(T,T)产生歧义

编译器调用函数的匹配过程如下:

  • 寻找和使用最符合函数名和参数类型的模板函数,找到则调用;

  • 否则,寻找一个函数模板,将其实例化产生一个可以匹配的模板函数,找到则调用;

  • 否则,寻找可以通过类型转换进行参数匹配的重载函数,找到则调用。

  • 否则调用错误。

    如果调用有多于一个的匹配选择,则调用匹配出现二义性,也是错误的。

3 类模板

3.1 类模板与模板类

一个类模板是类定义的一种模式,用于实现数据类型参数化的类。

类模板=模板说明+类说明

template <typename Type>//模板说明

class TClass   //类说明

{

//TClass 的成员函数

private  DateMember;

}

类属参数必须至少在类说明中出现一次
在这里插入图片描述

类模板的成员函数都是函数模板,实现语法和函数模板类似,如果在类中定义成员函数(inline),不需要特别说明,如果在类外定义,则每个成员函数定义都要冠以模板参数说明,并且指定类名时,后要跟类属参数

例如:**template开头,用Array:😗*表示类模板的成员函数.

template<typename T> Array<T>::Array(int s){  }
  • 当类模板实例化时,成员函数同时实例化为模板函数。
  • 声明一个对象的时候,必须用实际类型参数替换类属参数,将类模板实例化为模板类,类型参数用尖括号表示。
  • 创建对象:ArrayIntry(6);//用int 实例化,建立模板类对象。

3.2 类模板作为函数参数

函数的形式参数类型可以是类模板或类模板的引用。调用时对应的实际参数是该类模板实例化的模板类对象

当一个函数拥有类模板参数时,这个函数必定是函数模板。

3.3 在类层次中的类模板

4 标准模板

**前言:**C++包含一个有许多组件的标准库。标准模板库(STL)中有三个组件:容器(container)、迭代器(iterator)和算法(algorithm)。利用标准模板库进行编程,可以节省大量的时间和精力。

4.1 容器

“容器”是数据结构,是包含对象的对象。STL库提供的容器是常用数据结构的类模板(抽象了数据元素的具体类型,只关心结构的组织和算法,就是类模板)

1 容器分类

(1)顺序容器—提供顺序表的表示和操作

vector(向量):随机访问序列中的单个元素,在序列尾快速的插入和删除元素。如果在序列中插入和删除元素,时间和序列长度成正比

deque(双向队列):随机访问序列中的单个元素,可以在序列的头或尾快速插入和删除元素。如果在序列中插入和删除元素,时间和序列长度成正比

list(双向链表):用动态链式存放数据,可以从任何位置快速插入和删除元素。

C语言中的数组和string也是一种容器,称为近容器

(2)关联容器—提供集合和映像的表示和操作

set(集合):不允许重复值,快速查找。

multiset(集合):允许重复值,快速查找。

map(映像):一对一映射,不允许重复值;基于关键字的快速查找。

multimap(映像):一对多映射,允许重复值;基于关键字的快速查找。

(3)容器适配器----特殊顺序表

stack(堆栈):后进先出(LIFO)表,只能在表头插入和删除元素。

queue(队列):先进先出(FIFO)表,只能在表头删除元素,在表尾插入元素。

priority_queue(优先队列):优先级最高的元素总是第一个出列。

2 容器的接口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值