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

函数重载

在实际开发中,有时候需要实现几个功能类似的函数,只是细节有所不同。如交换两个变量的值,但这两种变量可以有多种类型,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.mfbz.cn/a/372415.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【新书推荐】6.2节 段寄存器

在16位汇编语言的源程序中&#xff0c;我们将源程序按照不同的功能和作用划分为若干个逻辑段&#xff0c;如数据段用来存储数据&#xff0c;代码段用来存储代码&#xff0c;堆栈段用来保存临时数据&#xff0c;附加段用来拷贝数据。我们可以把汇编语言的源程序抽象地理解为数据…

TCP与UDP:传输层协议的差异与选择

在计算机网络中&#xff0c;传输控制协议&#xff08;TCP&#xff09;和用户数据报协议&#xff08;UDP&#xff09;是两种常用的传输层协议。然而&#xff0c;随着互联网的快速发展&#xff0c;传统的TCP和UDP在某些场景下存在一些限制。为了解决这些问题&#xff0c;出现了新…

如何使用VS Code编写小游戏并实现公网游玩本地游戏【内网穿透】

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…

No matching client found for package name ‘com.unity3d.player‘

2024年2月5日更新 必须使用Unity方式接入Unity项目&#xff01;一句话解决所有问题。&#xff08;真的别玩Android方式&#xff09; 大致这问题出现原因是我在Unity采用了Android方式接入Firebase&#xff0c;而Android接入实际上和Unity接入方式有配置上的不一样&#xff0c;我…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…

链表经典算法(+OJ刷题)

文章目录 前言一、移除链表元素二、链表的中间节点三.反转链表四.合并两个有序链表五.分割链表六.环形链表的约瑟夫问题总结 创作不易&#xff0c;点赞收藏一下呗&#xff01;&#xff01;&#xff01; 前言 在上一节&#xff0c;我们介绍了单链表的增&#xff0c;删&#xff…

机器学习基础、数学统计学概念、模型基础技术名词及相关代码个人举例

1.机器学习基础 &#xff08;1&#xff09;机器学习概述 机器学习是一种人工智能&#xff08;AI&#xff09;的分支&#xff0c;通过使用统计学和计算机科学的技术&#xff0c;使计算机能够从数据中学习并自动改进性能&#xff0c;而无需进行明确的编程。它涉及构建和训练机器…

用Python实现MD5加密

用Python实现MD5加密 用Python实现MD5加密时用到的是hashlib模块&#xff0c;可以通过hashlib标准库使用 多种Hash算法&#xff0c;如SHA1 、SHA224 、SHA256 、SHA384 、SHA512和MD5算法 等。下面是通过调用hashlib模块对字符串进行MD5加密的简单实例&#xff1a; from hash…

[UI5 常用控件] 06.Splitter,ResponsiveSplitter

文章目录 前言1. Splitter1.1 属性 2. ResponsiveSplitter 前言 本章节记录常用控件Splitter,ResponsiveSplitter。主要功能是分割画面布局。 其路径分别是&#xff1a; sap.ui.layout.Splittersap.ui.layout.ResponsiveSplitter 1. Splitter 1.1 属性 orientation &#x…

DBeaver连接达梦数据库

1、下载驱动文件 可官网下载Hibernate 框架 | 达梦技术文档 (dameng.com) 1. 打开DBeaver软件&#xff0c;点击“数据库”&#xff0c;选择“驱动管理器” 2. 点击“新建”进行达人大金仓驱动管理器配置。 3、创建驱动-设置&#xff1a;驱动名称、类名、url 驱动名称&#…

(2017|ICLR,EBGAN,AE 鉴别器,正则化)基于能量的 GAN

Energy-based Generative Adversarial Network 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. EBGAN 模型 2.1 目标函数 2.2 解决方案的最优解 2.3 使用自动编码器 2.…

Android Button background 失效

问题 Android Button background 失效 详细问题 笔者开发Android项目&#xff0c;期望按照 android:background中所要求的颜色展示。 实际显示按照Android 默认颜色展示 解决方案 将xml的Button 组件修改为<android.widget.Button> 即将代码 <Buttonandroid:l…

RCS-YOLO复现

复现结果–Precision&#xff1a;0.941&#xff0c;Recall&#xff1a;0.945&#xff0c;AP 50 _{50} 50​&#xff1a;0.941&#xff0c;AP 50 : 95 _{50:95} 50:95​&#xff1a;0.693&#xff0c;误差在5个点内&#xff0c;可以接受 感想 第5篇完全复现的论文

Facebook与全球文化:多元化视角下的社交体验

在数字时代的今天&#xff0c;Facebook如一座横跨全球的桥梁&#xff0c;将人们从世界各地连接在一起。这个社交媒体平台已经不仅仅是一个在线社交的工具&#xff0c;更是一个全球化时代的文化交汇点。本文将深入研究Facebook在全球文化中的作用&#xff0c;以及它如何在多元文…

[python] 过年燃放烟花

目录 新年祝福语 一、作品展示 二、作品所用资源 三、代码与资源说明 四、代码库 五、完整代码 六、总结 新年祝福语 岁月总是悄然流转&#xff0c;让人感叹时间的飞逝&#xff0c;转眼间又快到了中国传统的新年&#xff08;龙年&#xff09;。 回首过去&#xf…

AUTOSAR内存篇 -EEPROM Abstraction(EA)

文章目录 功能介绍一般行为寻址机制和分段地址计算擦/写次数限制“立即” 数据的处理管理块一致性信息总结本文介绍关于EEPROM Abstraction相关的内容。下图所示为内存硬件抽象层的模块架构图。 EEPROM抽象(EA)从器件特定的寻址方案和分段中抽象出来,并为上层提供虚拟寻址方…

C++进阶--搜索二叉树

概念 搜索二叉树是一种特殊的二叉树&#xff0c;其具有以下特点&#xff1a; 1.对于每个结点&#xff0c;它的左子树中的所有节点的值都小于该节点的值&#xff0c;而右子树中的所有节点的值都大于该节点的值。 2.左子树和右子树都是搜索二叉树。 这个 特性使得搜索二叉树可…

PyTorch的10个基本张量操作

PyTorch是一个基于python的科学计算包。它的灵活性允许轻松集成新的数据类型和算法&#xff0c;并且框架也是高效和可扩展的&#xff0c;下面我们将介绍一些Pytorch的基本张量操作。 Tensors 张量Tensors是一个向量&#xff0c;矩阵或任何n维数组。这是深度学习的基本数据结构…

C语言贪吃蛇详解

个人简介&#xff1a;双非大二学生 个人博客&#xff1a;Monodye 今日鸡汤&#xff1a;人生就像一盒巧克力&#xff0c;你永远不知道下一块是什么味的 C语言基础刷题&#xff1a;牛客网在线编程_语法篇_基础语法 (nowcoder.com) 一.贪吃蛇游戏背景 贪吃蛇是久负盛名的游戏&…

图解报文网关:一种低代码报文网关的创新设计

所有的支付系统都对接了很多的外部支付、流出、外汇等各种类型的渠道&#xff0c;这些渠道的接口和报文格式各异。今天和大家一起聊聊如何实现一种简洁高效的低代码报文网关设计&#xff0c;主要包括&#xff1a;报文网关的定位&#xff0c;三种形态&#xff0c;低代码报文网关…