day44——C++对C的扩充

news2024/11/16 10:16:42

八、C++对函数的扩充

8.1 函数重载(overload)

1> 概念

函数重载就是能够实现"一名多用",是实现泛型编程的一种

泛型编程:试图以不变的代码,来实现可变的功能

2> 引入背景

程序员在写函数时,可能会出现这种情况:定义多个函数时,仅仅只是因为函数参数的类型不同或者函数参数个数的不同,导致同一个功能的函数需要定义多个不同名字。例如:两个整数求和、两个小数求和、三个整数求和。。。这些都只是实现求和功能,由于参数个数或参数类型的不同,就需要定义多个函数名字,用起来比较麻烦。

基于以上背景,C+引入了函数重载:运行在同一个作用域下,定义多个同名的函数。但是,要求这些同名的函数必须参数参数不同,后期调用时,系统会根据主调函数的实参去自动匹配相应的函数执行。

3> 要求:

函数名相同

形参列表必须不同

返回值无关

必须在同一个作用域下

#include <iostream>
 
 
using namespace std;
 
 
//定义两个整数的求和
int sum(int m, int n)
{
    return m+n;
}
 
 
//下面这个函数会报错,即使函数返回值和函数体内容不同,也不能构成重载
//void sum(int m, int n)
//{
//    return m-n;
//}
 
 
//定义两个小数的求和
float sum(float m, float n)
{
    return  m+n;
}
 
 
//定义两个double类型的数据求和
double sum(double m, double n)
{
    return m+n;
}
 
 
//定义三个整数的求和
int sum(int m, double n, int k)
{
    return m+n+k;
}
 
 
int main()
{
    cout<<sum(3,7)<<endl;        //10
 
 
 
 
    cout<<sum(3.5,7.5)<<endl;        //11
 
 
    cout<<sum(3,7.5, 6)<<endl;   //16
 
 
    return 0;
}
 
 
练习:定义函数分别求两个整数的最大值,两个小数的最大值,三个整数的最大值,并验证
Plain Text
自动换行

#include <iostream>
 
using namespace std;
//定义两个整数的求和
void max(int m,int n)
{
    if(m>n)
    {
        cout<< m <<"大" <<endl;
    }else
    {
         cout<< n <<"大" <<endl;
    }
}
//定义两个double小数的求和
void max(double m,double n)
{
    if(m>n)
    {
        cout<< m <<"大" <<endl;
    }else
    {
         cout<< n <<"大" <<endl;
    }
}
void max(int m,int n,int k)
{
    if(m>n)
    {
        if(m>k)
        {
            cout<< m <<"大" <<endl;
        }else
        {
            cout<< k <<"大" <<endl;
        }
    }else
    {
        if(n>k)
        {
            cout<< n <<"大" <<endl;
        }else
        {
            cout<< k <<"大" <<endl;
        }
    }
}
int main()
{
     max(3,7);
     max(1.12,2.22);
     max(1,2,3);
     max(1,3,3);
    return 0;
}

8.2 函数的默认参数

1> 引入目的:

程序员在定义函数时,可能会出现一个功能出现多个参数,但是,有时候,只需要传递其中某几个参数即可执行。此时,主调函数中传过来的参数,被调函数使用传过来的,主调函数没传过来的参数,被调函数使用自己的默认值

2> C++允许在定义函数时,给其中的某几个参数设置默认参数,对于设置了默认值的参数,主调函数传数据就使用主调函数传的,主调函数不传数据,就使用默认值

3> 默认参数的设置原则:靠右原则,也就是说必须当前参数的右边的形参设置了默认值后,当前参数才能设置默认值。

原因是,函数参数传递的过程是靠左原则,实参向形参传递时,向给左侧的形参赋值

4> 当函数重载和默认参数同时出现时,注意,如果带默认参数的函数包含了重载的函数,那么函数定义时没有问题,但是函数版调用时会不确定调用哪一个

5> 如果带默认参数的函数,声明和定义分开时,默认参数写在声明部分,定义部分就不写默认参数了

#include <iostream>
 
 
using namespace std;
 
 
int sum(int  = 0, int =0, int =100);    //函数声明
 
 
//定义重载函数时
//int sum(int x, int y):如果有默认参数包含了该函数,函数定义是没有问题,但是函数调用时会不知道调用哪一个
int sum(int x, double y)
{
    return x+y;
}
 
 
 
 
int main()
{
    cout << sum(2,3,5) << endl;       //调用了默认参数的函数,三个参数主调函数传递
 
 
    cout << sum(2,3) << endl;       //调用了默认参数的函数,前两个参数主调函数传递,后一个参数使用默认的
 
 
    cout << sum(2) << endl;       //调用了默认参数的函数,前一个参数主调函数传递,后两个参数使用默认的
 
 
    cout << sum() << endl;        //调用了默认参数的函数,三个参数使用的都是默认值
 
 
    return 0;
}
 
 
//函数定义在被调函数后面
int sum(int m , int n, int k)
{
    return m+n+k;
}

8.3 哑元

1> C++定义函数时,支持哑元,运行某个形参或某几个形参只有声明,没有实际意义,唯一的作用就是起到占位作用

#include <iostream>
 
 
using namespace std;
 
 
//该函数中的参数2就是一个哑元,只起到占位作用,不让程序优化后报错
int sum(int m, int, int k)
{
    return m+k;
}
 
 
 
 
 
 
int main()
{
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
    return 0;
}

2> 使用场景1:当某个程序已经发布后,随着技术的升级,可能会对某些函数进行优化,将原本有多个参数的函数,只需要少了的参数就可以完成,但是此时,未优化前的函数已经被多次调用,修改起来不方便,此时就可以在定义函数时,将被优化掉的形参设置成哑元,只起到接受数据的作用,并不起实际作用

3> 使用场景3:后期学习自增自减运算符重载时,用于区分前置和后置

8.4 内联函数

1> C++支持内联函数,使用关键字inline在函数定义前使用

2> 作用:被设置成内联函数的函数,在编译时,编译器会建议将内联函数自动展开,无需在运行时为该函数开辟内存空间,提高程序的执行效率

3> 内联函数的设置要求:

1、函数体积要小

2、调用比较频繁的函数

3、递归函数不能设置成内联函数

4、不足:如果大量使用内联函数,会使得主程序体积膨胀

#include <iostream>
 
 
using namespace std;
 
 
//该函数中的参数2就是一个哑元,只起到占位作用,不让程序优化后报错
inline int sum(int m, int, int k)
{
    return m+k;
}
 
int main()
{
    cout << sum(2,3,5) << endl;
    cout << sum(2,3,5) << endl;
 
    return 0;
}

4> 内联函数与带参宏的区别

在C++中,内联函数和带参宏虽然都可以用来在编译时展开代码以减少函数调用的开销,但它们之间存在几个关键的区别:
1. 类型检查
内联函数:内联函数是真正的函数,支持类型安全,会进行类型检查。
带参宏:宏只是预处理器的文本替换工具,不进行类型检查,容易引发类型相关的错误。
2. 编译器优化
内联函数:内联函数允许编译器进行更多优化,比如常量折叠、死代码消除等。
带参宏:宏展开后的代码通常不会受到这些优化的好处,因为它们在预处理阶段就已经被处理了。
3. 调试
内联函数:在调试时,内联函数可以像普通函数一样进行单步调试。
带参宏:宏在预处理阶段就已经被展开,这使得调试变得困难,因为它们在源代码中不再是独立的实体。
4. 作用域
内联函数:内联函数遵循正常的作用域规则。
带参宏:宏没有作用域的概念,它们可以在定义后的任何地方被展开,有时会导致意外的名字冲突。
5. 重复代码
内联函数:内联函数的代码在多个调用点展开时,编译器可以智能地处理,避免不必要的代码膨胀。
带参宏:宏每次使用时都会文本上的复制粘贴,可能会导致代码膨胀。

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

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

相关文章

某系统存在任意文件下载漏洞

穷者&#xff0c;谁不想达&#xff0c;达者&#xff0c;更畏惧穷。为求发达&#xff0c;穷人兢兢业业&#xff0c;辛辛苦苦&#xff0c;农耕其田&#xff0c;工利其器&#xff0c;商务其业&#xff0c;学读其书&#xff0c;人人都在独善其身&#xff0c;可除了那些少数的书生可…

VS2022打包Docker镜像

1. 前置环境 操作系统win10/win11 安装 Docker Desktop 2. 演示项目 https://gitee.com/izory/ZrAdminNetCore .net8 分支为例 3. 添加 docker支持 4. 配置工程文件 在.proj 文件加上 <ContainerRepository>ZrAdminCore</ContainerRepository> <Containe…

【C++ 面试 - 内存管理】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

视频压缩工具哪个好?视频压缩工具安利

还在为视频文件过大而烦恼吗&#xff1f;想要快速分享或上传视频却受限于空间或时间&#xff1f; 别担心&#xff0c;今天我来告诉你们&#xff1a;视频压缩成文件怎么弄。 无需复杂操作&#xff0c;轻松几步&#xff0c;就能让你的视频文件瘦身成功&#xff0c;既保留关键内…

深度学习基础—结构化机器学习项目

1.正交化 这是一个老式电视&#xff0c;有一组旋钮可以对画面进行调节&#xff0c;例如高度、宽度、画面梯形角度、画面位置、画面旋转等等&#xff0c;但是如果有一个旋钮&#xff0c;旋转时可以调节上面所有参数&#xff0c;那么就会出现一种情况&#xff1a;当前的画面高度和…

jconsole远程连接

jconsole可以远程连接的前提&#xff08;需要在部署应用时像下面示例这样设置&#xff09;&#xff1a; -Djava.rmi.server.hostname127.0.0.1 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port3214 -Dcom.sun.management.jmxremote.sslfalse -Dcom.sun.m…

milvus使用milvus migration工具迁移数据

1.前提&#xff1a;这个数据迁移工具是collection 维度的 2.文章内是2.3.1–》2.4.5数据迁移&#xff0c;公司内部需求&#xff0c;各位看官注意哈 官方架构图&#xff1a; 想要迁移的milvus 官方称之为&#xff1a;源source milvus 要迁入的表 目标的milvus 官方称之为&…

JWT结构详解与JWT设置

JWT结构详解与JWT设置 1. 什么是token2. 为什么要使用token3. 什么是JWT4. JWT的格式4.1 header4.2 payload4.3 signature 5. JWT校验流程6. JWT使用案例6.1 token的创建6.2 判断token是否可以刷新6.3 刷新token6.4 token的校验6.5 用户验证流程 1. 什么是token Token是服务端…

Prometheus+Grafana的安装和入门

概念 什么是Prometheus? Prometheus受启发于Google的Brogmon监控系统&#xff08;相似kubernetes是从Brog系统演变而来&#xff09;&#xff0c; 从 2012年开始由google工程师Soundclouds使用Go语言开发的开源监控报警系统和时序列数据库 (TSDB)。&#xff0c;并且与2015年早…

2017年系统架构师案例分析试题一

目录 案例 【题目】 【问题 1】(12 分) 【问题 2】(13 分) 答案 【问题 1】答案 【问题 2】答案 相关推荐 案例 阅读以下关于软件架构评估的叙述&#xff0c;在答题纸上回答问题 1 和问题 2。 【题目】 某单位为了建设健全的公路桥梁养护管理档案&#xff0c;拟开发一套公…

USB PHY—— PHY 基础

芯片厂商开发了一些 USB PHY 芯片&#xff0c;可以把 DP、DM上的差模信号转成共模信号。 USB PHY 负责最底层的信号转换&#xff0c;作用类似于网口的 PHY。 USB 信号传输前&#xff0c;需要通过 PHY 把 USB 控制器的数字信号转成线缆上的模拟信号。USB 控制器和 PHY 之间的总…

中国严肃游戏开发的最佳实践

严肃游戏产业在中国迅速发展&#xff0c;将娱乐与教育、培训和宣传活动融为一体。旨在实现特定学习成果或行为改变的严肃游戏在从企业培训到医疗保健和教育的各个领域越来越受欢迎。然而&#xff0c;为中国市场开发成功的严肃游戏需要深入了解当地文化、用户偏好和技术趋势。以…

函数栈帧的创建和销毁(VS2022)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、前面的困惑 二、什么是函数栈帧 三、关于函数栈帧的基础知识 1.栈 2.寄存器 2.1 什么是寄存器 2.2 相关的寄存器 2.3 相关汇编命令 2.4 预备知识 四、解析函数…

盘点4款可以免费使用的高效ai PPT制作工具。

平时我们自己制作一个PPT还是需要比较长的时间的&#xff0c;从构思内容&#xff0c;到制作主题和逻辑框架&#xff0c;然后是挑选模板、排版配色等&#xff0c;过程比较繁琐且费时。但是&#xff0c;现在出现了很多的AIPPT制作工具&#xff0c;能够快速的帮助用户生成一个完整…

来自工业界的知识库 RAG(六),独特的 RAG 框架 dsRAG 核心亮点解读

背景介绍 在前面介绍了较多的开源 RAG 框架&#xff0c;比如主打 Rerank 的 QAnything, 主打精细文件解析的 RagFlow, 主打模块化灵活组合的 GoMate。这些库的设计除了少量的独特之处外&#xff0c;相似的部分很多。 最近有注意到一款另类的 RAG 框架 dsRAG&#xff0c;使用了…

openGauss在龙芯平台部署的实践

服务器环境 系统信息 NAME"Loongnix-Server Linux" VERSION"8" ID"loongnix-server" ID_LIKE"rhel fedora centos" VERSION_ID"8" PLATFORM_ID"platform:lns8" PRETTY_NAME"Loongnix-Server Linux 8"…

第四十篇-TeslaP40+Ollama+Ollama-WebUI(自编译)

本文介绍用自己编辑ollama-webui,链接本地ollama 环境 系统&#xff1a;CentOS-7 CPU: 14C28T 内存&#xff1a;32G 显卡&#xff1a;Tesla P40 24G 驱动: 535 CUDA: 12.2 Ollama: 0.3.0本地ollama 参考 [第二十四篇-Ollama-在线安装](https://blog.csdn.net/hai4321/articl…

2024软考:一场与“难”共舞的奇妙冒险,你值得拥有!

在这个时代&#xff0c;如果说有什么考试能让IT界的勇士们闻风丧胆&#xff0c;又爱又恨&#xff0c;那软考绝对能C位出道&#xff0c;成为众多技术大佬心中的“白月光”与“朱砂痣”。随着岁月悠悠&#xff0c;2024年的软考似乎又悄悄地在难度上动了点小心思&#xff0c;让人不…

vue设置水印

水印图例 1.新建Watermark.js 文件 const watermark {}const setWatermark (text, sourceBody) > {const id Math.random() * 10000 - Math.random() * 10000 / Math.random() * 10000if (document.getElementById(id) ! null) {document.body.removeChild(document.getE…

阿里云服务器开放端口的完整版图文教程

原文&#xff1a;阿里云服务器开放端口完整版教程&#xff1a;https://www.yundashi168.com/488.html 笔者近期开发完成的服务端程序部署在阿里云的ECS云服务器上面&#xff0c;一些应用程序配置文件需要设置监听的端口&#xff08;如Tomcat的8080、443端口等&#xff09;&…