当前位置: 首页 > article >正文

C++ 泛型编程,函数模版和类模版

1.泛型编程

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

就比如说活字印刷术,就是提供一个模具,然后根据模具来印刷出不同的字。

泛型编程跟着类似,提供一个模版,根据这个模版由编译器自动生成不同的函数或者类

2.函数模版

2.1为什么要有函数模版

在c语言中,我们想交换两个整数、交换两个浮点数、交换自定义类型类型,我们必须自己手动写n个函数!!!并且每个函数的函数名都不一样!!!

void SwapInt(int& a,int& b)
{
	int c = a;
	a = b;
	b = c;
}
void SwapDouble(double& a, double& b)
{
	double c = a;
	a = b;
	b = c;
}

int main()
{
	int a1 = 1, b1 = 2;
	SwapInt(a1, b1);
	cout << a1 << " " << b1 << endl;
	double a2 = 1.1, b2 = 2.2;
	SwapDouble(a2, b2);
	cout << a2 << " " << b2 << endl;
	return 0;
}

有没有一种方法能使我们不用再写很多个函数,只用写一个函数(模版),就能完成各个类型的交换呢?这时候函数模版就登场了

2.2怎么使用函数模版

模版格式:

template<class T1,class T2,class T3...>

返回值 函数名(函数参数){  函数体  }

template<class T>
void Swap(T &a ,T &b)
{
	T c = a;
	a = b;
	b = c;
}
int main()
{
	int a1 = 1, b1 = 2;
	Swap(a1, b1);
	cout << a1 << " " << b1 << endl;
	double a2 = 1.1, b2 = 2.2;
	Swap(a2, b2);
	cout << a2 << " " << b2 << endl;
	return 0;
}

2.3函数模版的实例化

这里我们提供的swap是仅仅只是一个函数模版而已,并不是真正的函数,用不同类型的参数使用函数模板时需要由编译器自动生成一个相应的函数,这就叫做函数模版的实例化!!!

模版的实例化分为显示实例化隐式实例化

2.3.1隐式实例化

由编译器识别实参类型,推导出模版参数的类型

template<class T>
void Swap(T &a ,T &b)
{
	T c = a;
	a = b;
	b = c;
}
int main()
{
	int a1 = 1, b1 = 2;
	Swap(a1, b1);

	double a2 = 1.1, b2 = 2.2;
	Swap(a2, b2);
	return 0;
}

由传进来的参数推导出T的类型,这种就叫做隐式实例化

2.3.2显示实例化

在函数名后的<>中指定所传的具体类型

template<class T>
void Swap(T &a ,T &b)
{
	T c = a;
	a = b;
	b = c;
}
int main()
{
	int a1 = 1, b1 = 2;
	Swap<int>(a1, b1);

	double a2 = 1.1, b2 = 2.2;
	Swap<double>(a2, b2);
	return 0;
}

3.类模版

3.1为什么需要有类模版

当我们需要两个栈,一个栈存int类型,一个存double类型时,我们又只能自己写两个不同的类,这两个类 类名不同,但是类中除了类型,其他的都是一样的!!!

class StackInt
{
public:
	StackInt(int capacity = 4)
	{
		_a = new int[capacity];
		_top = 0;
		_capacity = capacity;
	}
	~StackInt()
	{
		delete[] _a;
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
class StackDouble
{
public:
	StackDouble(int capacity = 4)
	{
		_a = new double[capacity];
		_top = 0;
		_capacity = capacity;
	}
	~StackDouble()
	{
		delete[] _a;
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	double* _a;
	int _top;
	int _capacity;
};

int main()
{
	StackInt st1;
	StackDouble st2;
	return 0;
}

这时候就需要用到我们的类模版来解决这个问题了.

3.2怎么使用类模版

模版格式:

template<class T1,class T2,class T3...>

class 类名 {  成员函数和成员变量  };

template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = new T[capacity];
		_top = 0;
		_capacity = capacity;
	}
	~Stack()
	{
		delete[] _a;
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	T* _a;
	int _top;
	int _capacity;
};


int main()
{
	Stack<int> st1;
	Stack<double> st2;
	return 0;
}

3.3类模版的实例化

类模版的实例化和函数模版的实例化不同,类模版的实例化是在类名后加<>,在<>中加上实例化的类型, 类模板名字不是真正的类,而实例化的结果才是真正的类

Stack是类名

Stack<int>是类型


http://www.kler.cn/a/148406.html

相关文章:

  • ESLint 使用教程(五):ESLint 和 Prettier 的结合使用与冲突解决
  • JavaWeb后端开发知识储备1
  • C 语言 【模拟实现内存库函数】
  • 比ChatGPT更酷的AI工具
  • TortoiseSVN提示服务器凭证检核错误:站点名称不符
  • AcWing 302 任务安排 斜率优化的dp
  • 高等数学零基础篇复习笔记
  • 离线配置conda环境
  • 基于Python的网络爬虫设计与实现
  • LeetCode-805.保持城市天际线 C/C++实现 超详细思路及过程[M]
  • Android BSP 开发之六
  • 什么是网络爬虫技术?它的重要用途有哪些?
  • 商用车的智慧眼车规级激光雷达
  • java 系统属性和环境属性
  • 计算机网络基础知识自用
  • 【微服务专题】微服务架构演进
  • Spring Boot 3.2.0 虚拟线程初体验 (部分装配解析)
  • Linux内存管理(六十四):ION 内存管理器——system heap
  • VMware虚机重启后静态IP不生效
  • QT linux下应用程序打包
  • uni-app中vue3+setup实现下拉刷新、上拉加载更多效果
  • 角色管理--高级产品经理岗
  • uniapp 导航分类
  • Vue表单的整体处理
  • 成为AI产品经理——模型评估概述
  • GeoTrust证书