【C->Cpp】由C迈向Cpp(3)


正文开始:

目录

(一)函数重载

 (1)函数重载

(2)函数重载实现原理

(二) 引用

(1)引用

(2)语法

         i ,别名:

        ii,传参:

        iii,返回值:

        iv,修改外部变量:

        v,避免空指针:


(一)函数重载

 (1)函数重载

        C语言不允许出现多个同名函数,而C++支持出现同名函数,这需要通过函数重载实现。 

        函数重载是指在一个类中,有多个同名的函数,但它们的参数列表不同。在C++中,函数重载可以通过函数名相同但参数列表不同来实现,参数列表不同可以包括参数类型、参数个数或者参数顺序等。当调用函数时,编译器会根据参数的类型或个数来自动选择合适的函数进行调用。

(2)函数重载实现原理

        在Linux下,C++函数重载的实现原理是使用了一种叫做"名称修饰"(Name Mangling)的技术。当C++源代码被编译成目标文件时,编译器会对函数的名称进行修饰,以区分不同的重载函数。

        名称修饰的过程是由编译器自动完成的,它将根据函数的参数类型、参数个数和参数顺序等信息生成一个唯一的符号名。这样,在目标文件中就能够通过不同的符号名来区分不同的重载函数。

(下面一linux的g++为例)

linux下的g++函数在修饰后变成:{   _Z + 函数名长度 + 函数名 + 类型首字母   }

 

//实例如下
Add(int,int)       ->   call     _Z3Addii
Add(double,double) ->   call     _Z3Adddd
//只要类型不同,类型顺序不同,类型个数不同,都可以让修饰后函数名不同,
//编译器可以区分不同的函数名,这样就构成了重载

        编译同一个文件,对于文件中的同一个函数,用gcc和g++编译出来的函数名称是不同的(符合上面规则):

用gcc编译的函数func1函数:

用g++编译的函数func1函数:

函数重载的作用主要有以下几点:

  1. 提高代码的复用性:通过函数重载,可以在一个类中定义多个功能相似的函数,避免了重复编写代码的问题。
  2. 提高程序的可读性:使用函数重载可以让程序更加直观清晰,减少了函数命名的复杂性。
  3. 增强了函数的灵活性:通过函数重载可以根据不同的参数选择不同的实现方式,从而提供了更多的选择。

        需要注意以下几点:

  • 重载函数的返回类型不可以作为重载的条件,只有参数列表不同才能作为重载的条件。
  • 重载函数的参数列表必须不同,参数个数不同或者参数类型不同都可以作为重载的条件。
  • 重载函数可以有不同的访问修饰符,比如一个是私有的,一个是公有的。

 

        需要注意的是,C++规定了可以函数重载,但是具体实现的名称修饰规则是由编译器决定的,不同的编译器可能会有不同的修饰规则。

(二) 引用

(1)引用

        引用不是新定义一个变量,而是给已存在的变量取了一个别名, 编译器不会为引用变量开辟内存空间,它和它引用的变量共同用一块内存空间

 

(2)语法

         i ,别名:

        引用提供了一个变量的别名,可以通过引用来访问已经存在的变量。这使得代码更加清晰和易读,同时也让函数传参更加方便,避免了拷贝大量数据的开销。

基本使用:

int i = 0;
int& j = i;//给i取别名j,j是i的别名

        j与i共用同一块内存地址;

        对i与对j的运算是等同的,j++后 i = 1 (其实就是i++ 后 i = 1); 

(引用类型必须和引用实体是同种类型的)

引用的特性:

        引用在定义时必须初始化;

        一个变量可以有多个引用;

 可以对别名取别名(套娃)对别名取别名,其实就是对原变量取别名,原变量与他的别名的地位是等同的(一个空间的名字可以是 “ i ”也可以是 “ j ” );

        引用一旦引用一个实体,不能再引用其他实体;

        引用需要与创建变量区分:

int i = 0; 
int j = i;//创建一个变量j初始化为0

        ii,传参:

        引用作为函数参数,可以将参数按引用传递,而不是按值传递。这样可以避免参数的拷贝,提高函数的执行效率,并且可以在函数内部修改参数的值(也就相当于传址),使得函数能够对传入的参数进行修改(同时也更好理解)。

 

//形参直接用实参的别名接收,便于直接对实参操作
void swap(int& r1,int& r2)
{
    int tem = r1;
    r1 = r2;
    r2 = tem;
}
int main()
{
    int a = 1,b = 2;
    swap(a,b);//不用再传地址,更好理解

    return 0;
}

 

        iii,返回值:

        函数可以返回引用类型,这样可以避免拷贝对象的开销,同时也方便链式调用和对象的赋值操作。通过返回引用,函数可以返回一个指向已存在的对象的引用,而不需要创建新的对象。

        对于n,是局部变量,存储在栈区,出count函数就会被销毁;

        编译器会先将n的值存储在寄存器中,当count函数栈帧销毁后,将寄存器的值赋给ret;

int count()
{
    int n = 0;
    n++;
    return n;
}

int main()
{

    int ret = count();
    
    return 0;
}

        对于变量n,是静态变量,存储在静态区,不会随着count函数的销毁而销毁;

        编译器仍然会先将n的值存储在寄存器中,当count函数栈帧销毁后,将寄存器的值赋给ret;

int count()
{
    static int n = 0;
    n++;
    return n;
}

int main()
{

    int ret = count();
    
    return 0;
}

        为什么两种都需要寄存器的帮助?

        如果是返回引用,还需要寄存器的帮助吗?

​
int& count1()
{
    int n = 0;
    n++;
    return n;
}

int& count2()
{
    static int n = 0;
    n++;
    return n;
}

int main()
{

    int ret1 = count1();
    int ret2 = count2();
    return 0;
}

​

        显然不需要,这样就减少了拷贝;

        引用作返回值,同时也可以做可修改的左值,因为引用本质上就是变量的别名,变量当然可修改;

#define N 50

//静态顺序表
struct AY
{
    int a[N];
    int size;    //大小
    int capacity;//容量
}

//检查是否越界
int& posAt(AY& ay,int i)
{
    assert(i < N)
    return ay.a[i];
}

int main()
{
    AY ay;
    for(int i = 0;i < N;i++)
    {
        posAt(ay,i) = i * 10;//返回引用可作为可被修改的左值
    }
}


        iv,修改外部变量:

        引用可以作为函数的返回值,在函数内部对外部的变量进行修改。这种方式可以用于实现一些特殊的操作,如对象的赋值操作符重载等。通过引用,可以直接修改外部的变量,而不需要通过指针等方式。

 

        v,避免空指针:

        引用在定义时必须初始化,并且不能被修改指向其他对象,这样可以避免了指针的空引用问题。使用引用可以更加安全地操作对象,避免了空指针异常的发生。

 


 完~

未经作者同意禁止转载

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

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

相关文章

HDR 摄影

HDR 摄影&#xff0c;即高动态范围 High Dynamic Range摄影&#xff0c;旨在通过合并不同曝光值的照片来捕捉场景中从最亮到最暗部分的全部细节。 这种技术对于在一个图像中展现广泛的亮度范围特别有用&#xff0c;尤其是在自然光线条件下&#xff0c;如直射日光或阴影区域&…

单片机学习笔记---LED呼吸灯直流电机调速

目录 LED呼吸灯 直流电机调速 模型结构 波形 定时器初始化函数 中断函数 主程序 上一节讲了电机的工作原理&#xff0c;这一节开始代码演示&#xff01; 我们上一篇说Ton的时间长Toff时间短电机会快&#xff0c;Ton的时间短Toff时间长电机会慢 并且我们还要保证无论Ton和…

『运维备忘录』之 Sed 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

【镜头知识】对焦和变焦

前言 变焦 调整某几个镜片的相对位置&#xff0c;从而改变镜片组的焦距&#xff0c;进而改变图像的视场角度。 焦距和视角以及拍摄距离的关系这张图能更好的体现&#xff1a; 视角越窄&#xff0c;也意味着放大的倍数越大&#xff01; 对焦 物体反射的光线&#xff0c;有很多不…

高B格可视化大屏设计具备的10大特征

简洁明了&#xff1a; 可视化大屏界面应该尽可能简洁明了&#xff0c;突出重点&#xff0c;避免过多的信息和视觉干扰。同时&#xff0c;需要考虑到用户的视觉效果和易用性&#xff0c;使用户能够迅速地获取所需信息。 数据精准&#xff1a; 可视化大屏界面显示的数据应该准确…

秒懂百科,C++如此简单丨第二十天:贪心算法2

目录 Everyday English 前言 洛谷 P1031 均分纸牌 题目描述 思路点拨 AC代码 洛谷 P1094 纪念品分组 题目描述 样例输入 样例输出 思路点拨 AC代码 洛谷 P2660 zzc 种田 题目描述 思路点拨 AC Code 结尾 Everyday English Dont miss the opportunity. 机不可…

代码随想录 Leetcode435. 无重叠区间

题目&#xff1a; 代码(首刷看解析 2024年2月17日&#xff09;&#xff1a; class Solution { private:const static bool cmp(vector<int>& a,vector<int>& b) {return a[0] < b[0];} public:int eraseOverlapIntervals(vector<vector<int>&…

离线数仓(二)【用户行为日志采集平台搭建】

用户行为日志采集平台搭建 1、用户行为日志概述 用户行为日志的内容&#xff0c;主要包括用户的各项行为信息以及行为所处的环境信息。收集这些信息的主要目的是优化产品和为各项分析统计指标提供数据支撑。收集这些信息的手段通常为埋点。 目前主流的埋点方式&#xff0c;有代…

C++文件操作->文本文件(->写文件、读文件)、二进制文件(->写文件、读文件)

#include<iostream> using namespace std; #include <fstream>//头文件包含 //文本文件 写文件 void test01() { //1.包含头文件 fstream //2.创建流对象 ofstream ofs; //3.指定打开方式 ofs.open("test.txt", ios::out); //4.写…

【杂谈】裁我?我是研发,我是研发啊!

闲谈 这两年互联网是越来越不太平了&#xff0c;前有国外互联网裁员的妖风四起&#xff0c;后来寒气又传到国内&#xff0c;让我们这群打工人叫苦连天。最近有部电影蛮火的&#xff0c;叫《年会不能停》&#xff0c;感觉跟我前司很相似&#xff0c;不过好像由于今年业绩不太行…

第1集《佛遗教经》

《佛遗教经》和尚尼慈悲&#xff0c;诸位法师、诸位居士&#xff0c;阿弥陀佛&#xff01;好&#xff0c;请放掌。 我们从今天开始有六个讲次&#xff0c;跟大家共同学习《佛遗教经》。在正式讲这部经之前&#xff0c;我想先简单的说明本经的特色。 身为一个佛弟子&#xff0…

OpenCV-40 绘制直方图

一、使用matplotlib画直方图 可以利用matplotlib把OpenCV统计得到的直方图绘制出来 示例代码如下&#xff1a; import cv2 import matplotlib.pyplot as pltlena cv2.imread("beautiful women.png") # 变为黑白图片 gray cv2.cvtColor(lena, cv2.COLOR_BGR2GRAY…

《Linux 简易速速上手小册》第8章: 安全性与加固(2024 最新版)

文章目录 8.1 防火墙与安全策略8.1.1 重点基础知识8.1.2 重点案例&#xff1a;配置 iptables 以保护 Web 服务器8.1.3 拓展案例 1&#xff1a;使用 firewalld 配置动态防御区域8.1.4 拓展案例 2&#xff1a;配置 ufw 以简化管理 8.2 SSH 安全最佳实践8.2.1 重点基础知识8.2.2 重…

人工智能学习与实训笔记(六):神经网络之智能推荐系统

人工智能学习笔记汇总链接&#xff1a;人工智能学习与实训笔记汇总-CSDN博客 本篇目录 七、智能推荐系统处理 7.1 常用的推荐系统算法 7.2 如何实现推荐 7.3 基于飞桨实现的电影推荐模型 7.3.1 电影数据类型 7.3.2 数据处理 7.3.4 数据读取器 7.3.4 网络构建 7.3.4.1…

vue-ESlint (六)

代码规范 代码规范&#xff1a;一套写代码的约定规则。例如&#xff1a;"赋值符号的左右是否需要空格" "一句结束是否是要加;" . 老话说&#xff1a;"没有规矩不成方圆" → 正规的团队 需要 统一的编码风格 JavaScript Standard Style 规范说…

成本效能FinOps: Crane 部署

目录 一、实验 1.环境 2.安装kind 3.安装Crane 二、问题 1.脚本安装prometheus报错 2.查看集群信息失败 3.Helm添加grafana 报错 4.查看crane资源失败 5.prometheus部署时kube-state-metrics 拉取镜像显示ImagePullBackOff 6.Crane 功能与架构 一、实验 1.环境 &a…

智慧公厕的主要应用

在现代社会中&#xff0c;随着城市化进程的加速推进&#xff0c;公共卫生设施的建设和管理变得愈加重要。而智慧公厕作为一种新型城市公共设施&#xff0c;正以其智能化、高效化的特点&#xff0c;成为改善城市卫生环境的重要手段。智慧公厕运用物联网、互联网、大数据、云计算…

HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例

HAL/LL/STD STM32 U8g2库 I2C SSD1306/sh1106 WouoUI磁贴案例 &#x1f4cd;基于STM32F103C8T6 LL库驱动版本&#xff1a;https://gitee.com/chcsx/platform-test/tree/master/MDK-ARM&#x1f3ac;视频演示&#xff1a; WouoUI移植磁贴案例&#xff0c;新增确认弹窗 &#x1f…

无人驾驶LQR控制算法 c++ 实现

参考博客&#xff1a; &#xff08;1&#xff09;LQR的理解与运用 第一期——理解篇 &#xff08;2&#xff09;线性二次型调节器(LQR)原理详解 &#xff08;3&#xff09;LQR控制基本原理&#xff08;包括Riccati方程具体推导过程&#xff09; &#xff08;4&#xff09;【基础…

精品jsp+ssm鲜花销售管理系统-购物商城

《[含文档PPT源码等]精品jspssm鲜花销售管理系统[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 使用技术&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#x…