C++ 函数重载(多态)、函数模板

2023-11-12

内容均出自《C++ primer plus》,本文仅为个人理解总结所用。
若有不明欢迎站内私信交流。
若发现文中错漏之处,期待不吝赐教站内私信。

(一)函数重载(多态)

先上定义:

C++ Premer Plus (page276)

  • 函数多态是C++在C语言的基础上新增的功能。
  • 术语"多态":指的是有多种形式。
  • 术语"函数重载":指的是可以有多个同名函数,因此对名称进行了重载。
  • 两个术语是同一回事,但通常使用函数重载。
  • 函数多态(函数重载)让程序能够使用多个同名的函数。

实例理解:

同名函数,程序如何区分需要使用哪个?
——根据特征标

  • 函数重载的关键是函数的参数列表——也称为特征标
  • 若参数数目/参数类型不同,则特征标也不同。
  • tips: const限定符、 &引用符不为特征标
//比如本组函数
void print(const char* str, int width);		//#1
void print(double d, int width);			//#2
void print(long l, int width);				//#3
void print(int i, int width);				//#4
void print(const char *str);				//#5

使用print( )函数时,编译器将根据所采用的的用法使用有相应特征标的原型:

printf("Pancakes", 15);						//自动匹配#1
printf("Syrup");							//自动匹配#5
printf(1999.0, 10);							//自动匹配#2
printf(1999, 12);							//自动匹配#4
printf(1999L, 15);							//自动匹配#3
  • tips: 特别注意:const限定符、 &引用符不为特征标

(二)函数模板

先上定义

函数模板是通用的函数描述,使用泛型来定义函数,其中的泛型可用具体的类型(如int 或 double)替换。
通过类型作为参数传给模板,可使编译器生成该类型的函数。

使用场景分析:

  • 假设我们需要交换两个int变量的值的函数,一般来说则直接撸:
void swap(int &a, int &b)
{
	int tmp;
	tmp = a;
	a = b;
	b = tmp;
}
  • 现在我们新增了需求,要求增加一个交换double变量的值的函数,一般来说可以再加一个函数:
void swap(double &a, double &b)
{
	double tmp;
	tmp = a;
	a = b;
	b = tmp;
}
  • 那如果需求又增加了呢?要求char,short,float,long都来一套?
  • 方法一:都来一套也行。
  • 方法二:
    它们做一模一样的事情,只是参数类型不同
    C++允许以任意类型的方式来定义函数:函数模板;

函数模板建立

template <typename AnyType>				//紫色字体:关键字  黑色字体:类型名称
void swap(AnyType &a, AnyType &b)
{
	AnyType tmp;
	tmp = a;
	a = b;
	b = tmp;
}

对,就这么简单,这就是泛型基本概念。

Tips:

  • 模板并不创建函数,而只是告诉编译器如何定义函数。
  • 需要交换int数据时,编译器将按模板模式创建这样的函数,并用int 代替 AnyType。(实例化/隐式实例化)
  • 同样,需要交换double 时,编译器将按模板模式创建这样的函数,并用double代替 AnyType。
  • C++98 添加关键字typename之前,C++使用关键字class来创建模板。
template <class AnyType>
void swap(AnyType &a, AnyType &b)
{
	AnyType tmp;
	tmp = a;
	a = b;
	b = tmp;
}

模板显示实例化声明

建立模板之后,发现我其实只需要用short 和 int 两种,那我直接告诉编译器我需要这两个。
隐式实例化:声明模板,编译器自动创建
显示实例化: 声明模板,告诉编译器通过模板创建我需要的类型。
区别:隐式实例化,编译器发现函数需要使用,才创建实例。 显示实例化,不管有没有使用都创建实例。

//建立函数模板
template <typename AnyType>				//紫色字体:关键字  黑色字体:类型名称
void swap(AnyType &a, AnyType &b)
{
	AnyType tmp;
	tmp = a;
	a = b;
	b = tmp;
}
//声明即可,编译器会创建int实例
template void swap<int>(int, int);


(三)重载的模板

简单示例笔记

template <typename AnyType>					//#1
void swap(AnyType &a, AnyType &b)			//模板 + 特征标为两个引用变量
{
	AnyType tmp;
	tmp = a;
	a = b;
	b = tmp;
}

template <typename AnyType>					//#2
void swap(AnyType a[], AnyType b[], int n)	//模板 + 特征标为两个数组、一个整型
{
	AnyType tmp;
	int i;
	for(i = 0; i< n; i++){
		tmp = a[i];
		a[i] = b[i];
		b[i] = tmp;
	}
}

(四)模板具体化

理解完重载和模板函数之后,如果还不晕的话。
那么,继续。

假设有个需求:
众所周知,结构体是可以直接赋值的。
但是我只想交换结构体里面salary, floor 两个变量值
因此我希望调用swap如果传入的是job(指定类型)的话,执行指定处理

struct job
{
	char name;				//姓名
	double salary;			//薪资
	int floor;				//楼层
};

template <> void swap<job>(job &j1, job &j2)		//模板具体化
{
	double salary;
	salary = j1.salary;
	j1.salary = j2.salary;
	j2.salary = j1.salary;

	int floor;
	floor = j1.floor;
	j1.floor = j2.floor;
	j2.floor = j1.floor;	
}

(五)要点总结

  • 重载:同名函数,根据特征标(参数数目/参数类型)不同而匹配不同的处理函数。
  • const限定符、&引用符,不计入特征标。
  • 模板:定义函数模板,编译器生成对应不同数据类型相同操作函数实例。
  • 隐式实例化:定义模板,编译器自动创建
  • 显示实例化: 定义模板,手动告诉编译器该创建哪个类型。
  • 可重载模板 = 重载 + 模板
  • 具体化:不使用模板生成函数,定义一个指定具体类型的全新函数。
  • 区分实例化和具体化
    实例化:使用模板,只需要声明,编译器就会生成指定类型的实例。
    具体化:不使用模板,需要再编写函数定义。

补充:

  • 以上均为同名函数,编译器会自动匹配,匹配规则十分细密,后续学习了以后再整理。
  • 也可以编写代码,引导编译器匹配我们希望它匹配的函数。
//单纯比较
template<typename T>			//#1
T lesser(T &a, T &b)
{
 return a < b? a : b;
}

//比较绝对值
int lesser( int a, int b)		//#2
{
 a = a< 0? -a : a;
 b = b< 0? -b : b;
return a < b? a : b;
}

int m = 20;
int n = -30;
double x = 15.5;
double y = 25.9;
函数调用方式 编译器寻找匹配函数
lesser(m , n) int类型,匹配 int lesser( int a, int b)
lesser(x , y) double类型,匹配模板,并且生成double实例
lesser<>(m , n) int类型,但调用处增加<> ,匹配模板,并且生成int实例
lesser(m , n) int类型,但调用处增加<int> ,匹配模板,并且生成int实例
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 函数重载(多态)、函数模板 的相关文章

随机推荐

  • 深入了解React:组件化开发与状态管理

    简介 React是一个流行的JavaScript库 用于构建用户界面 它以其高效的虚拟DOM和组件化开发的思想而闻名 使得构建复杂的Web应用程序变得更加简单和可维护 本篇博客将带您深入了解React的基本概念 组件化开发和状态管理 帮助您
  • FISCO BCOS(三十六)———Python Sdk window环境部署及应用开发

    1 环境要求 Python环境 python 3 6 3 3 7 3 最好是3 7 3 因为我是 FISCO BCOS节点 可以直接建链 可以是节点前置 也可以是一键部署 2 安装python 2 1 python下载地址 https ww
  • COM 组件设计与应用(十一)

    COM 组件设计与应用 十一 IDispatch 及双接口的调用作者 杨老师 下载源代码一 前言 前段时间 由于工作比较忙 没有能及时地写作 其间收到了很多网友的来信询问和鼓励 在此一并表示感谢 咳 我也需要工作来养家糊口呀 上回书介绍了两
  • linux系统函数总结(一)

    realpath include
  • c陷阱与缺陷

    第一章 词法陷阱 1 这一章没有太多 干货 唯一比较有趣的就是 1 3 语法分析中的 贪心法 所讲内容 这个 贪心 就是编译器会读入字符 如果能新读入的字符和之前所读入字符能组成符号 则编译器会继续读入下一个字符 直到读入的字符不能和之前的
  • BLE MESH组网(五)配置BLE MESH

    BLE MESH 五 配置BLE MESH 前言 概述 配置协议 供应程序 信标 邀请 交换公钥 前言 2017 年 5 月 全球最臭名昭著的勒索软件 WannaCry 在全球范围内积极攻击计算机 劫持用户数据索要赎金 这次攻击影响了 15
  • kafka性能参数和压力测试揭秘

    上一篇文章介绍了Kafka在设计上是如何来保证高时效 大吞吐量的 主要的内容集中在底层原理和架构上 属于理论知识范畴 这次我们站在应用和运维的角度 聊一聊集群到位后要怎么才能最好的配置参数和进行测试性能 Kafka的配置详尽且复杂 想要进行
  • 空间坐标系坐标变换及matlab代码实现

    1 前言 下文中描述坐标系使用了英文的简写 OS Origin Space 原始空间坐标系 NS New Space 新空间坐标系 2 坐标变换介绍 为了解决这个问题 可以利用机器人学中的位姿变换来进行描述 以下依次介绍坐标平移 坐标旋转和
  • j2ee mysql struts_Java新手如何学习Spring、Struts、Hibernate三大框架?

    如何通过java开发培训成为java技术抓紧 这里面java的基础语法很重要 同时 要从基础开始到java的深度编程 这里提炼出一些技术知识点 来避免一些误区 拉勾IT课小编为大家分解 这里面的一些技巧 1 避免使用正则表达式 正则表达式给
  • K8S第三讲 Kubernetes集群配置网络插件

    在Kubernetes集群中 网络插件是必需的 因为它们为Pod提供了可访问的IP地址 并确保它们能够相互通信 Kubernetes支持多种网络插件 包括Calico Flannel Weave Net等 这里以Calico为例介绍如何配置
  • 通过数组下标获取值都有哪些方法_js: 数组

    定义 数组是一种有序数据结合 创建方式 直接量 var a 1 2 构造函数 var b new Array 1 2 注意 构造函数中只传一个参数会变成长度 数组API var arr 0 1 2 push 添加元素 返回length 并把
  • Vue 艺术字体下载、设置

    1 本人常用的下载地址 https zh fonts2u com 2 找到你需要的字体点击下载 3 下载完之后有一个ttf文件 4 在vue里面 我个人在assets文件下创建一个文件夹 叫什么名字都行 找到你下载的ttf文件 把ttf文件
  • 【笔记】c编译执行过程

    c语言 c gt exe 过程 E 预处理 把 h和 c展开形成一个文件 宏定义直接替换 库文件 头文件打开 生成 i文件 gcc E hello c o hello i S 编译 i生成一个汇编代码文件 s gcc S hello i o
  • ES6 Symbol

    概览 const mySymbol Symbol mySymbol console log mySymbol Symbol mySymbol console log mySymbol Symbol mySymbol false consol
  • 收藏!生物信息学数据库大全,全网最全收集整理!

    综合数据库 INSD 国际核酸序列数据库 International Nucleotide Sequence Databank 由日本的DDBJ 欧洲的EMBL和美国的GenBank三家各自建立和共同维护 EMBL库 欧洲分子生物学实验室的
  • MySQL 全面知识总结

    基础 Mysql存储特点 Mysql存储数据以数据页为最小单位 在同一个数据页中 数据按照主键 连续存储 如果没有主键 则按照Mysql维护的 ROW ID 来连续存储 数据页和数据页之间以双向链表关联 数据和数据之间以单向链表关联 SQL
  • Go基础(复杂类型):结构体

    结构体 一个结构体 struct 就是一个字段的集合 而 type 的含义跟其字面意思相符 下面来写一个简单的例子 package main import fmt 一个结构体就是一个字段的集合 type Vertex struct X in
  • MATLAB机器人工具箱1-位姿描述及轨迹

    1 位姿描述 1 1 二维空间位姿描述 开启机器人工具箱 startup rvc 代码 clc clear 开启机器人工具箱 startup rvc 二维平面内的位姿描述 T1 SE2 1 2 30 pi 180 建立齐次坐标变换 代表 1
  • SSM毕业设计分享 疫情防控物业管理系统

    文章目录 1 项目简介 2 实现效果 2 1 界面展示 3 设计方案 3 1 概述 3 2 开发环境 3 3 系统结构设计 4 项目获取 1 项目简介 Hi 各位同学好呀 这里是M学姐 今天向大家分享一个今年 2022 最新完成的毕业设计项
  • C++ 函数重载(多态)、函数模板

    内容均出自 C primer plus 本文仅为个人理解总结所用 若有不明欢迎站内私信交流 若发现文中错漏之处 期待不吝赐教站内私信 一 函数重载 多态 先上定义 C Premer Plus page276 函数多态是C 在C语言的基础上新