【C++】模版(初阶)

目录

[一. 函数模版](#一. 函数模版)

[1. 格式 原理](#1. 格式 原理)

[2. 函数模版的实例化](#2. 函数模版的实例化)

[二. 类模板](#二. 类模板)


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

使用函数重载太麻烦

模具,填充不同类型,生成具体类型的代码

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

一. 函数模版

1. 格式 原理

template<typename T1, typename T2, ......, typename Tn>
返回类型 函数名(参数列表)
{ }

typename 是用来定义模板参数关键字也可以使用class,不能使用struct

模板参数作用范围:紧跟的 { }

cpp 复制代码
template<typename T> // 模板参数 -- 类型
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

template<typename T1, typename T2>
T1 Func (const T1& x, const T2& y)
{
	cout << x << " " << y << endl;
	return x;
}

cpp 复制代码
int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	Swap(a, b);
	Swap(c, d);

	// Date d1(1949, 10, 1), d2(2015, 7, 3);

    Func(1, 2);
    Func(1, 2.2);
    
	return 0;
}

调用的是模版实例化出的函数(模板就是将本来应该我们做的重复的事情交给了编译器 )


C++库里面有。不需要写Swap,也不用写模版。直接使用

cpp 复制代码
int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	swap(a, b);
	swap(c, d);

	// Date d1(1949, 10, 1), d2(2015, 7, 3);

	return 0;
}

2. 函数模版的实例化

隐式实例化:让编译器根据实参 推演模板参数的实际类型
显示实例化:在函数名后的<>中 指定模板参数的实际类型

cpp 复制代码
template<typename T>
T Add(const T& left, const T& right)
{
	return left + right;
}

template<typename T>
T* Alloc(int n)
{
    return new T[n];
}

int main()
{ 
	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;
	cout << Add(a1, a2) << endl;
	cout << Add(d1, d2) << endl;

	// cout << Add(a1, d1) << endl; 报错:编译器无法确定T的类型

	// 解决方案1:用户自己强制转换
	cout << Add(a1, (int)d1) << endl;
	cout << Add((double)a1, d1) << endl;

	// 解决方案2:显示实例化
    cout << Add<int>(a1, d1) << endl;
	cout << Add<double>(a1, d1) << endl;

	// 有些函数无法自动推,只能显示实例化
	double* p1 = Alloc<double>(10);

	return 0;
}

类型转换会产生临时变量(常性)。Add(a1, (int)d1) 这里不是把 d1 传给 right,所以 Add 要加 const

二. 类模板

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

普通类,类名和类型是一样
类模板,类名和类型不一样
类名:Stack
类型:Stack<T>

构造函数不一定用T这个参数,所以类模板都无法通过推演实例化,类都是显示实例化


cpp 复制代码
template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = new T[capacity];

		_capacity = capacity;
		_size = 0;
	}

	void Push(const T& Date)
	{
		// CheckCapacity();
		_a[_size] = Date;
		_size++;
	}

	~Stack()
	{
		if (_a)
		{
			free(_a);
			_a = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}

private:
	T* _a;
	int _capacity;
	int _size;
};

int main()
{
	Stack<int> s1;    // int
	Stack<double> s2; // double
	Stack<char> s3;   // char
	
	// Stack<int, double>s4; 多个模板参数

	return 0;
}

类模板的声明和定义分离是别致的

类模板的声明和定义最好不要分离到 2个文件,会报错(后面讲)

cpp 复制代码
template<class T>
class Stack
{
public:
	Stack(int capacity = 4);

	void Push(const T& Date);

	~Stack()
	{
		if (_a)
		{
			free(_a);
			_a = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}


private:
	T* _a;
	int _capacity;
	int _size;
};

template<class T>
Stack<T>::Stack(int capacity)
{
	_a = new T[capacity];

	_capacity = capacity;
	_size = 0;
}

template<class T>
void Stack<T>::Push(const T& data)
{
	// CheckCapacity();
	_a[_size] = data;
	_size++;
}

本篇的分享就到这里了,感谢观看 ,如果对你有帮助,别忘了点赞+收藏+关注

小编会以自己学习过程中遇到的问题为素材,持续为您推送文章

相关推荐
2401_868534788 小时前
RTOS之RT-Thread & Linux:线程/进程管理与调度核心差异分析
c++·python
郝学胜-神的一滴9 小时前
Qt 高级编程 040:按钮悬浮弹出滑块弹窗的完整攻略
开发语言·c++·qt·软件工程·用户界面
程序喵大人14 小时前
【C++进阶】STL算法与函数对象 - 02 sort为什么需要随机访问迭代器
开发语言·c++·算法
ZhangShao060714 小时前
题解:CF2249B
c++·算法
吹什么轩16 小时前
c++复习:map和set的使用
开发语言·c++
fpcc16 小时前
跟我学C++中级篇—内存流
开发语言·c++
吹什么轩18 小时前
c++复习:模拟实现list来更好的理解和应用list
开发语言·c++
AmyLin_200118 小时前
PDF 色彩保真工程实践【5】核心实现(下):拼装 Image XObject、页面资源与内容流
c++·pdf·sdk·颜色空间·印刷·icc·cmyk
乱七八糟的屋子19 小时前
MTL4 (Matrix Template Library) 超详细实战教程|C++高性能稠密/稀疏矩阵计算
c++·矩阵·稀疏矩阵·mtl4·matrixtemplate·c++线性代数·高性能数值计算
依然鸣20 小时前
PTA团体程序设计天梯赛L2真题讲解L2-045-048
数据结构·c++·经验分享·学习·算法·pat考试·pat