【C++入门篇 - 10】:模板

模板的概念

  1. 泛型编程:指的是编写与类型无关的逻辑代码,在泛型编程中,编写的代码可以作用多种类型的对象
  2. 模板:就是实现代码重用的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了代码的重用性。模板就是泛型编程的基础
  3. 模板分类:函数模板、类模板

函数模板

函数模板:函数模板不是一个实体函数,编译器不会对一个函数模板生成可执行代码。定义函数模板之后只是说对一个函数功能框架的一个描述。只有在调用的时候才会为其生成可执行代码

函数模板和模板函数的区别

  • 函数模板:是模板,函数的模板
  • 模板函数:函数,通过函数的模板产生的一个函数

函数模板的定义

  • template 关键字,表示模板
  • <>表示类型参数列表,类似函数的参数列表,只不过类型参数列表中的参数为类型参数
  • typename 类型名(还有一个修饰类型的关键叫 class)
#include<iostream>

template<typename T>
T myAdd(T a, T b)
{
	return a + b;
}

template<class T1>
T1 mySub(T1 a, T1 b)
{
	return a - b;
}

void main()
{
	printf("%d\n", myAdd(1, 2));
	printf("%f\n", myAdd(1.1f, 2.3f));
}

template<class T>
T mydev(T a, T b)
{
	return a / b;
}

在这里插入图片描述

观察以上代码,T mydev(T a, T b)是在main函数后,但是运行成功,体现了只有在调用的时候才会为其生成可执行代码这个特性。当把T mydev(T a, T b)函数中的分号去掉时也不会报错,只有在调用时才会报错。

隐式推导和显示推导

  • 观察以下报错,报错原因:1是整型,1.2是浮点型,这样是无法推导出模板的T类型,只能用显示推导
    在这里插入图片描述
    在这里插入图片描述

模板与模板可以重载,模板与普通函数可以重载

  • 模板和模板进行重载只需要函数名相同,参数列表不同(函数的参数列表或者是模板的类型参数列表)
  • 调用函数,优先匹配参数完全吻合的普通函数,匹配不上,再匹配函数模板,如果还匹配不上,再匹配能否经过强转执行普通函数
    在这里插入图片描述

不能对结构体进行相加,若想相加必须重载运算符
(除通用性操作(排序、数组的增删改查等)需要模板,大部分情况不需要用模板)
在这里插入图片描述

类模板

类模板:是一个类类型的样板,不能直接使用
模板类:通过类模板生成的一个具体类型的类类型

以下是类模板的一个代码示例:

#include<iostream>
template<typename T>
class MyArr
{
	T *pArr;
	int len;
	int maxSize;
public:
	MyArr()
	{
		pArr = NULL;
		len = maxSize = 0;
	}
	~MyArr()
	{
		if (pArr)
			delete[] pArr;
		pArr = NULL;
	}
	void setMaxSize(int m)
	{
		maxSize = m;
	}
	bool insert(int index, T const& data)
	{
		if (index < 0 || index >= maxSize)
			return false;
		
		if (pArr == NULL)
			pArr = new T[maxSize];

		if (index > len)
		{
			pArr[len++] = data;
		}
		else
		{
			for (int i = len; i > index; --i)
			{
				pArr[i] = pArr[i - 1];
			}
			pArr[index] = data;
			len++;
		}
		return true;
	}
};

void main()
{
	//函数有参数列表,可以推导类型参数,类没有参数列表,只能显示表示模板类
	MyArr<int> m;
	m.setMaxSize(10);
	m.insert(5, 100);
	m.insert(0, 101);
}

在这里插入图片描述

类模板不分文件编写

  • 先用文件编写的方式创建一个类
    在这里插入图片描述

  • 在头文件中编写类模板
    在这里插入图片描述

  • 在.cpp文件中发现类的构造和析构是不合法的
    在这里插入图片描述

  • 原因:因为在模板编译时不会生成可执行代码,所以虽然text是类名,但是现在还没有类,只有模板。而我们在分文件编写中提到,所有不产生内存的都写在.h文件中,.cpp文件是需要写带内存的东西。所以我们可以改为以下形式:
    在这里插入图片描述

  • 在主函数中调用:
    在这里插入图片描述

类模板写一个栈

  • 创建一个stack.h头文件,并写入栈结构
#pragma once

template<class T, int maxSize>
class CMyStack //栈结构
{
	T stackArr[maxSize];
	int top;
public:
	CMyStack();
	~CMyStack();
	void push(T const& data); //入栈
	void pop(); //出栈
	T getTop() const; //得到栈顶元素
}; 

template<class T, int maxSize>
T CMyStack<T, maxSize>::getTop() const
{
	return stackArr[top - 1];
}

template<class T, int maxSize>
void CMyStack<T, maxSize>::pop()
{
	top--;
}

template<class T, int maxSize>
void CMyStack<T, maxSize>::push(T const& data)
{
	stackArr[top++] = data;
}

template <class T, int maxSize>
CMyStack<T, maxSize>::CMyStack()
{
	top = 0;
}

template <class T, int maxSize>
CMyStack<T, maxSize>::~CMyStack()
{

}
  • 在主函数中运行
    在这里插入图片描述

类模板中的一些特殊情况

template <class T, int val>
class CA
{
	T arr[val];
};

template<class T1>
void fun1(CA<T1, 10> & a){} //函数是模板,且把模板参数给到函数自己的参数中的类模板

template<class T1, class T2>
void fun2(CA<T1, 20> & a)	//函数是模板,且模板参数分两类,一类给到自己函数体用,一类给到参数中的类模板用
{
	T2 val;
}
  • 基类是模板,派生类也是模板
class CX
{

};

template<class T>
class CY : public CX
{

};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值