C++之函数重载,默认参数,bool类型,inline函数,异常安全

news2024/12/26 0:03:33

函数重载

在实际开发中,有时候需要实现几个功能类似的函数,只是细节有所不同。如交换两个变量的值,但这两种变量可以有多种类型,short, int, float等。在C语言中,必须要设计出不同名的函数,其原型类似于:

void swap1(short *, short *);
void swap2(int *, int *);
void swap3(float *, float *);

但在C++中,这完全没有必要。C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数重载(Function Overloading)。借助重载,一个函数名可以有多种用途。
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
C++进行函数重载的实现原理叫名字改编(name mangling),具体的规则是:
1. 函数名称必须相同 。
2. 参数列表必须不同(参数的类型不同、个数不同、顺序不同)。
3. 函数的返回类型可以相同也可以不相同
4. 仅仅返回类型不同不足以成为函数的重载

默认参数

默认参数的目的

C++可以给函数定义默认参数值。通常,调用函数时,要为函数的每个参数给定对应的实参。

void func1(int x, int y);
void func1(int x, int y)
{
  cout << "x = " << x << endl;
  cout << "y = " << y << endl;
}

无论何时调用func1函数,都必须要给其传递两个参数。但C++可以给参数定义默认值,如果将func1函数参数中的x定义成默认值0, y定义成默认值0,只需简单的将函数声明改成

void func1(int x = 0, int y = 0); 

这样调用时,若不给参数传递实参,则func1函数会按指定的默认值进行工作。允许函数设置默认参数值,是为了让编程简单,让编译器做更多的检查错误工作

默认参数的声明

一般默认参数在函数声明中提供。当一个函数既有声明又有定义时,只需要在其中一个中设置默认值即可。若在定义时而不是在声明时置默认值,那么函数定义一定要在函数的调用之前。因为声明时已经给编译器一个该函数的向导,所以只在定义时设默认值时,编译器只有检查到定义时才知道函数使用了默认值。若先调用后定义,在调用时编译器并不知道哪个参数设了默认值。所以我们通常是将默认值的设置放在声明中而不是定义中。

默认参数的顺序规定

如果一个函数中有多个默认参数,则形参分布中,默认参数应从右至左连续定义。当调用函数时,只能向左匹配参数。如:

void func2(int a = 1, int b, int c = 0, int d);//error
void func2(int a, int b, int c = 0, int d = 0);//ok

若给某一参数设置了默认值,那么在参数表中其后所有的参数都必须也设置默认值,否则,由于函数调用时可不列出已设置默认值的参数,编译器无法判断在调用时是否有参数遗漏

默认参数与函数重载

默认参数可将一系列简单的重载函数合成为一个。例如:

void func3();
void func3(int x);
void func3(int x, int y);
//上面三个函数可以合成下面这一个
void func3(int x = 0, int y = 0);

如果一组重载函数(可能带有默认参数)都允许相同实参个数的调用,将会引起调用的二义性。如下代码就是错误的:

void func4(int);
void func4(int x, int y = 0);
void func4(int x = 0, int y = 0);

所以在函数重载时,要谨慎使用默认参数。

bool类型

在C++中,还添加了一种基本类型,就是bool类型,用来表示true和false。true和false是字面值,可以通过转换变为int类型,true为1,false为0.

int x = true;// 1
int y = false;// 0

任何数字或指针值都可以隐式转换为bool值。
任何非零值都将转换为true,而零值转换为false.

一个bool类型的数据占据的内存空间大小为1

inline函数

在C++中,通常定义以下函数来求取两个整数的最大值

int max(int x, int y)
{
  return x > y ? x : y;
}

为这么一个小的操作定义一个函数的好处有:
1.阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多;
2.如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多;
3.使用函数可以确保统一的行为,每个测试都保证以相同的方式实现;
4.函数可以重用,不必为其他应用程序重写代码。
虽然有这么多好处,但是写成函数有一个潜在的缺点:调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器,并在返回时恢复,复制实参,程序还必须转向一个新位置执行。即对于这种简短的语句使用函数开销太大。
在C语言中,我们使用带参数的宏定义这种借助编译器的优化技术来减少程序的执行时间,那么在C++中有没有相同的技术或者更好的实现方法呢?答案是有的,那就是内联(inline)函数。内联函数作为编译器优化手段的一种技术,在降低运行时间上非常有用。

什么是内联函数?

内联函数是C++的增强特性之一,用来降低程序的运行时间。当内联函数收到编译器的指示时,即可发生内联:编译器将使用函数的定义体来替代函数调用语句,这种替代行为发生在编译阶段而非程序运行阶段。
定义函数时,在函数的最前面以关键字“inline”声明函数,即可使函数称为内联声明函数。

inline int max(int x, y)
{
  return x > y ? x : y;
}

谨慎地使用内联

异常安全

异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。

throw表达式

抛出异常即检测是否产生异常,在C++中,其采用throw语句来实现,如果检测到产生异常,则抛出异常。该语句的格式为:

throw 表达式;

异常是一个表达式,其值的类型可以是基本类型,也可以是类
举个例子:

double division(double x, double y)
{
  if(y == 0)
    throw "Division by zero condition!";
  return x / y;
}

try-catch语句块

try-catch语句块的语法如下:

try
{
  //语句块
}
catch(异常类型)
{
  //具体的异常处理...
}
...
catch(异常类型)
{
  //具体的异常处理...
}

try...catch语句块的catch可以有多个,但至少要有一个。
try...catch语句的执行过程是:
执行 try块中的语句,如果执行的过程中没有异常拋出,那么执行完后就执行最后一个 catch块后面的语句,所有 catch块中的语句都不会被执行;
如果 try块执行的过程中拋出了异常,那么拋出异常后立即跳转到第一个“异常类型”和拋出的异常类型匹配的 catch块中执行(称作异常被该 catch块“捕获”),执行完后再跳转到最后一个 catch块后面继续执行。
举个例子:

void test()
{
  double x, y;
  cin >> x >> y;
  try
 {
    if(0 == y)
   {
      throw y;
   } 
    else
   {
      cout << (x / y) << endl;
   }   
 }
  catch(double d)
 {
    cout << "catch(double)" << endl;
 }
  catch(int e)
 {
    cout << "catch(int)" << endl;
 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DockerUI如何部署结合内网穿透实现公网环境管理本地docker容器

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

如何部署Linux AMH服务器管理面板并结合内网穿透远程访问

文章目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管…

容器和镜像

容器和镜像是现代软件开发和部署中重要的概念&#xff0c;它们通常与容器化技术&#xff08;如Docker&#xff09;相关联。以下是它们的基本定义和关系&#xff1a; 容器(Container): 容器是一种轻量级、可移植的运行环境&#xff0c;其中包含了应用程序及其依赖项&#xff08;…

leet code141. 环形链表(投机取巧法)只要9行代码!!不看后悔!

今天在力扣上做到这个题 当我看到了10000时我突然想到一种很投机取巧的方法&#xff0c;我们直接链表循环&#xff0c;然后当它循环到10001次的时候我们就直接能说明它是循环链表了&#xff01; 代码实现(小学生都能看懂) bool hasCycle(struct ListNode *head) { int add…

【HarmonyOS应用开发】APP应用的通知(十五)

相关介绍 通知旨在让用户以合适的方式及时获得有用的新消息&#xff0c;帮助用户高效地处理任务。应用可以通过通知接口发送通知消息&#xff0c;用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用&#xff0c;通知主要有以下使用场景&#xff1a; 显示接收…

黑豹程序员-ElementPlus支持树型组件带图标以及icon避坑

效果 vue代码 参数说明&#xff1a;node当前节点&#xff0c;data当前节点后台传入数据。 el-tree自身不支持图标&#xff0c;需要自己去利于实现&#xff0c;并有个坑&#xff0c;和elementui写法不同。 <el-col :span"12"><el-form-item label"绑定…

Spring Web Header 解析常见错误

在上一章&#xff0c;我们梳理了 URL 相关错误。实际上&#xff0c;对于一个 HTTP 请求而言&#xff0c;URL 固然重要&#xff0c;但是为了便于用户使用&#xff0c;URL 的长度有限&#xff0c;所能携带的信息也因此受到了制约。 如果想提供更多的信息&#xff0c;Header 往往…

对多面体数据进行裁剪和加盖的功能

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example demo解决问题&#xff1a;对多面体数据进行裁剪和加盖的功能。 关键点&#xff1a; 创建了一个平面&#xff0c;并将其定位在输入多面体数据的中心位置&#xff…

Python 数据分析(PYDA)第三版(六)

原文&#xff1a;wesmckinney.com/book/ 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 十二、Python 建模库介绍 原文&#xff1a;wesmckinney.com/book/modeling 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 此开放访问网络版本的《Python 数据分析第三版…

【Vue】3-3、Vue 3.3 新特性 Pinia

一、Vue 3.3 新特性 1、defineOptions 有 <script setup> 之前&#xff0c;如果要定义 props&#xff0c;emits 可以轻而易举地添加一个与 setup 平级的属性 但是用了 <script setup> 后&#xff0c;就没法这么干了&#xff0c;setup 属性已经没有了&#xff0c…

Pyth 预言机: 它们如何影响Hover?

所有链上借贷市场都使用一种称为“oracle&#xff08;预言机&#xff09;”的服务&#xff0c;为dApp提供代币定价。Oracle是一个数据系统&#xff0c;将链下信息&#xff08;例如KuCoin上的BTC/USDT价格&#xff09;传递到链上合约。从那里&#xff0c;应用程序可以支付一小笔…

Matplotlib 绘图实践:从基础到高级技巧【第62篇—python:Matplotlib绘图】

文章目录 Matplotlib绘图模块基础入门大全1. 安装Matplotlib2. 绘制基本图形3. 自定义图形样式4. 多子图布局5. 高级绘图技巧6. 绘制实时动态图7. 图形注释与标记8. 颜色映射与散点图9. 绘制直方图10. 绘制饼图11. 绘制热力图 总结 Matplotlib绘图模块基础入门大全 Matplotlib…

RabbitMQ-1.介绍与安装

介绍与安装 1.RabbitMQ1.0.技术选型1.1.安装1.2.收发消息1.2.1.交换机1.2.2.队列1.2.3.绑定关系1.2.4.发送消息 1.2.数据隔离1.2.1.用户管理1.2.3.virtual host 1.RabbitMQ 1.0.技术选型 消息Broker&#xff0c;目前常见的实现方案就是消息队列&#xff08;MessageQueue&…

深度神经网络中的BNN和DNN:基于存内计算的原理、实现与能量效率

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言内存计算体系结构深度神经网络&#xff08;DNN&#xff09;随机梯度的优…

搭建自己的私服 maven 仓库

申明&#xff1a;本文章所使用docker-compose配置文件纯属学习运用&#xff0c;非商用如有雷同请联系本人协调处理。 一、配置docker-compose.yml文件 # 指定docker-compose的版本 version: 3 services: nexus: container_name: nexus_container image: sonatype/nex…

扩展鸿蒙ArkUI日期组件

鸿蒙ArkUI日期组件使用的是DatePickerDialog.show基础上扩展的表单式输入组件&#xff0c;方便在输入日期方式快速使用及复用。 /*** 日期*/ Component export default struct DiygwDate{//绑定的值Link Watch(onValue) value:string;// 隐藏值State valueField: string valu…

【机器学习】某闯关类手游用户流失预测

Final Project: 某闯关类手游用户流失预测 1 案例简介 手游在当下的日常娱乐中占据着主导性地位&#xff0c;成为人们生活中放松身心的一种有效途径。近年来&#xff0c;各种类型的手游&#xff0c;尤其是闯关类的休闲手游&#xff0c;由于其对碎片化时间的利用取得了非常广泛…

Sui上TVL突破5亿美元,位列DeFi榜单前十名和最活跃链前五名

2023年Sui上DeFi协议迅速增长&#xff0c;2024年这一势头仍在继续&#xff0c;根据DeFiLlama报告Sui上TVL近期超过5亿美元。在不到一年的时间里就达到这个金额&#xff0c;得益于Sui的突破性指标&#xff0c;比如其峰值TPS接近6,000。 Sui TVL突破5亿美元&#xff0c;登上DeFi…

使用VASPKIT生成非整数倍扩胞结构

在计算某些任务时需要根据原胞进行非对称或者根号倍扩胞&#xff0c;使用vaspkit可以构建一个扩胞倍数矩阵&#xff0c;这样可以获得特定方向非整数倍的扩胞结构。 这里使用的命令为vaspkit的400模块 注意400的命令会让你连续输入三行&#xff0c;每行都需要三个数值&#xff0…

Android 数据恢复电脑版免费下载使用方法 [2024 更新]

“我一直在寻找一款可以下载的适用于 PC 的优秀 Android 数据恢复软件。有很多&#xff0c;但大部分都需要我付费。你能推荐一个好的让我免费下载吗&#xff1f;” 奇客数据恢复安卓版是恢复已删除或丢失的 Android 数据的最安全的工具。免费下载下面的奇客数据恢复安卓版来尝试…