【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;
}

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

相关推荐
车载小杜13 分钟前
基于指针的线程池
开发语言·c++
uhakadotcom24 分钟前
Apache Airflow入门指南:数据管道的强大工具
算法·面试·github
跳跳糖炒酸奶1 小时前
第四章、Isaacsim在GUI中构建机器人(2):组装一个简单的机器人
人工智能·python·算法·ubuntu·机器人
绵绵细雨中的乡音1 小时前
动态规划-第六篇
算法·动态规划
程序员黄同学1 小时前
动态规划,如何应用动态规划解决实际问题?
算法·动态规划
march_birds1 小时前
FreeRTOS 与 RT-Thread 事件组对比分析
c语言·单片机·算法·系统架构
小麦嵌入式2 小时前
Linux驱动开发实战(十一):GPIO子系统深度解析与RGB LED驱动实践
linux·c语言·驱动开发·stm32·嵌入式硬件·物联网·ubuntu
斯汤雷2 小时前
Matlab绘图案例,设置图片大小,坐标轴比例为黄金比
数据库·人工智能·算法·matlab·信息可视化
云 无 心 以 出 岫2 小时前
贪心算法QwQ
数据结构·c++·算法·贪心算法
俏布斯3 小时前
算法日常记录
java·算法·leetcode