【c++】模板初阶

泛型编程

泛型编程:C++中一种使用模板来实现代码重用和类型安全的编程范式。它允许程序员编写与数据类型无关的代码,从而可以用相同的代码逻辑处理不同的数据类型。模板是泛型编程的基础

模板

模板分为两类:

  • 函数模板
  • 类模板

函数模板

函数模板:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生
函数的特定类型版本。

//函数模板格式
template<class T>
void Sawp(T& left,T& right)
{
	T tmp=left;
	left=right;
	right=tmp;
}

代码中的class也可也换成typename,但记住,class不能用struct代替。

原理: 编译器通过你编写的模板,再根据你传入的参数,自行生成对应的函数,调用的就是这个编译器自行生成的函数

假设你传入的两个参数都是int,那么编译器就会创建一个形参是int类型的模板
假设你传入的两个参数都是double,那么编译器就会创建一个形参是double类型的模板

举个例子:

//这里两处函数调用,看似调用的是一个函数,但实际上时调用了两个函数
//(函数调用要建立栈帧,一个是int类型,一个double类型,类型大小都不一样,更不可能调用的是同一个函数了),
//这个可以从汇编层来观察
template<typename T>
void Swap(T& left,T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
int main()
{
	int x = 1, y = 2;
	double m = 1.1, n = 2.2;
	Swap(x,y);
	Swap(m,n);
	return 0;
}

在这里插入图片描述

但如果你传入的参数,一个是int类型,一个是double类型,那么模板参数就不能这么写。

template<class T1,class T2>
void Sawp( T1& left, T2& right)
{
 T1 temp = left;
 left = right;
 right = temp;
}

像这样的,只有一个模板参数的,一次只能接收一个类型,当你把第一个int类型的参数传进来后,第二个double类型的参数它就穿不进来了,因为模板函数不允许自动类型转换。
在这里插入图片描述

函数模板实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化

  • 隐式实例化
  • 显示实例化

隐式实例化

template<typename T>
void Swap(const T& left,const T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
int main()
{
	int x=1,y=2;
	double m=1.1,n=2.2;
	
	Sawp(x,y);//这便是隐式实例化,不显示的规定模板参数的实际类型
 	
 	
 	return 0;
}

显示实例化

template<typename T>
void Swap(const T& left,const T& right)//因为显示实例化存在类型转换,所以需要加const
{
	T temp = left;
	left = right;
	right = temp;
}
int main()
{
	int x=1,y=2;
	double m=1.1,n=2.2;
	
	Sawp<int>(x,m);//这是显示实例化,通过函数名后的<>来显示的规定模板参数的实际类型
	Sawp(x,(int)m);//这不是显示实例化,但是你也可以通过强转来通过编译
 	
 	return 0;
}

模板参数的匹配原则

一个非模板函数允许和一个同名的模板函数同时存在。

在这里插入图片描述
当非模板函数满足调用条件时,则会直接调用非模板函数,如果不满足条件,则会调用模板函数。
在这里插入图片描述

在这里插入图片描述

类模板

类模板的定义格式

template<class T1,class T2....class Tn>
class 类模板名
{
	//....
};

举个例子:

template<class T>
class Stakc
{
public:
	Stack(size_t capacity = 4)
	{
		_array = new T[capacity];
		_capacity = capacity;
		_size = 0;
	}


private:
	T* _array;
	size_t _size;
	size_t _capacity;
};

模板不建议声明和定义分开来写:

template<class T>
class Stakc
{
public:
	Stack(size_t capacity = 4)
	{
		_array = new T[capacity];
		_capacity = capacity;
		_size = 0;
	}
	
	void Push(const T& data);

private:
	T* _array;
	size_t _size;
	size_t _capacity;
};

template<class T>
void Stack<int>::Push(const T& data)
{	
	// 扩容
	_array[_size] = data;
	++_size;
}

类模板实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值