【C++】——初识模版

文章目录

前言

当我们使用一个通用的函数:

cpp 复制代码
//为每一个类型都编写一个重载版本
void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}
void Swap(char& left, char& right)
{
	char temp = left;
	left = right;
	right = temp;
}

这种方法的缺点是显而易见的:随着需要交换的类型的增加,你需要不断地编写新的重载函数。这不仅繁琐,而且不灵活,因为它不能自动适应未来可能出现的新类型。

函数模板提供了一种更加灵活和通用的解决方案。你可以定义一个模板函数,该函数可以接受任意类型的参数,并在编译时根据传入的参数类型生成相应的函数版本。

函数模版

函数模版的格式:

template<typename T1, typename T2,...,typename Tn>

返回值类型 函数名(参数列表){}

cpp 复制代码
//函数模版
template<class T>
void Swap(T& m, T& n)
{
	T tmp = m;
	m = n;
	n = tmp;
}

注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)

cpp 复制代码
template<typename T>
void Swap(T& m, T& n)
{
	T temp = m;
	m = n;
	n = temp;
}
cpp 复制代码
template<class T>
void Swap(T& m, T& n)
{
	T tmp = m;
	m = n;
	n = tmp;
}
int main()
{
	int i = 1, j = 2;
	double x = 1.1, y = 2.2;
	Swap(i, j);
	Swap(x, y);
	//Swap(i, x); 函数模版不能传不同类型的参数
	return 0;
}

函数模版的原理

函数模版本身并不是函数,模版只是将我们做的事重复的事交给了编译器

函数模版的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

这里就是要解决这个问题

有两种处理方式

  1. 强制类型转换
  2. 使用显式实例化
cpp 复制代码
template<class T>
void Swap(const T& m, const T& n)
{
	T tmp = m;
	m = n;
	n = tmp;
}
int main()
{
	int i = 1, j = 2;
	double x = 1.1, y = 2.2;
	//推导实例化(自己动手强转)
	Swap(i, (int)x);
	Swap((double)i, x);
	//显示实例化
	Swap<int>(i, x);
	return 0;
}

如果我就要用 Swap(i,x) 来实现呢?

cpp 复制代码
template<class T1,class T2>
T1 Swap(const T1& m, const T2& n)
{
	T1 tmp = m;
	m = n;
	n = tmp;
}

有种场景我们必须用显示实例化:

cpp 复制代码
template<class T>
T* func1(int n)
{
	return new T[n];
}
int main()
{
	//func1(10); 编译器无法推导出类型
	int* p = func1<int>(10);
	return 0;
}

如果函数和模板同时存在,会先调用函数

cpp 复制代码
template<class T>
T ADD(const T& left, const T& right)
{
	return left + right;
}
int ADD(const int& x, const int& y)
{
	return (x + y) * 10;
}
int main()
{
	int a = 5;
	int b = 10;
	cout<<ADD(a, b)<<endl;

	return 0;
}

类模版

类模版的格式:

cpp 复制代码
template<class T1, class T2, ..., class Tn>
class 类模板名
{
 // 类内成员定义
}; 

类模版实现栈

cpp 复制代码
template<class T>
class Stack
{
public:
	Stack(int n = 4)
		:_arr(new T[n])
		,_size(0)
		,_capacity(n)
	{}
	~Stack()
	{
		delete[] _arr;
		_arr = nullptr;
		_size = _capacity = 0;
	}
	void Push(const T& x)
	{
		if (_size == _capacity)
		{
			T* tmp = new T[_capacity * 2];
			memcpy(tmp, _arr, sizeof(T) * _size);
			delete[] _arr;
			_arr = tmp;
			_capacity *= 2;
		}
		_arr[_size++] = x;
	}
	//...
private:
	T* _arr;
	int _size;
	int _capacity;
};

将栈的所有数据和方法封装在类内部,所以只有类成员函数才可以访问(最好不要类里声明,类外定义,除非在类外使用template<>语法来指明你正在定义的是哪个模板参数的成员函数),而且,通过类模版,不同的类型都可以实现栈,安全性也得到了提升。

cpp 复制代码
template<class T>
void Stack<T>::Push(const T& x)
{
	if (_size == _capacity)
	{
		T* tmp = new T[_capacity * 2];
		memcpy(tmp, _arr, sizeof(T) * _size);
		delete[] _arr;
		_arr = tmp;
		_capacity *= 2;
	}
	_arr[_size++] = x;
}

类模版的实例化

类模版只能使用显示实例化

cpp 复制代码
int main()
{
	Stack<int>str1;
	str1.Push(1);
	str1.Push(2);
	str1.Push(3);

	Stack<double>str2;
	str2.Push(1.1);
	str2.Push(2.2);
	str2.Push(3.3);
	return 0;
}

希望这篇博客对你有所帮助!!!

相关推荐
cookies_s_s20 分钟前
LRU Cache 最近最少使用
c++
前端小刘哥33 分钟前
赋能在线教育与企业培训:视频直播点播平台EasyDSS视频点播的核心技术与应用实践
算法
吗~喽40 分钟前
【LeetCode】四数之和
算法·leetcode·职场和发展
Net_Walke1 小时前
【散列函数】哈希函数简介
算法·哈希算法
郝学胜-神的一滴1 小时前
深入解析Linux下的`lseek`函数:文件定位与操作的艺术
linux·运维·服务器·开发语言·c++·软件工程
卿言卿语1 小时前
CC1-二叉树的最小深度
java·数据结构·算法·leetcode·职场和发展
码流之上1 小时前
【一看就会一写就废 指间算法】执行操作后的最大 MEX —— 同余、哈希表
算法·面试
仰泳的熊猫1 小时前
LeetCode:889. 根据前序和后序遍历构造二叉树
数据结构·c++·算法
2025年一定要上岸2 小时前
【日常学习】10-15 学习re
学习·算法·正则表达式
aramae2 小时前
数据结构与算法(递归)
开发语言·经验分享·笔记·算法