C++之 引用(refer)

2023-11-04

  1. 含义:变量的别名(第二名称)

  1. 作用:使用别名访问原名的内存空间,即别名与原名保存同样的内存空间

  1. 语法: 数据类型 + & + 别名 + 原名;(int &b=a;)

  1. 注意事项:

①引用必须要初始化

对于一个变量a,不能直接写int &b;而需要写int &b=a;

②引用在初始化后不可修改(不可再指向别的内存空间)
  1. 引用作函数参数:

作用:函数传参时,可以使用引用使得形参修饰实参

下面以 交换数字 的函数来做说明

void Swap01(int a, int b) 
{  // 值传递,不改变实参
    int tmp = a;
    a = b;
    b = tmp;
}

void Swap02(int* a, int* b)
{    // 址传递,改变实参
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

void Swap03(int &a, int &b)
{    // &a直接访问实参中的a空间,实现修改实参的效果
    int tmp = a;
    a = b;
    b = tmp;
}

在一定程度上简化了指针修改实参

  1. 引用作函数返回值

作用:可以作为函数的返回值存在
注意:不要返回局部变量引用
①如果返回了局部变量引用

int& test01()
{
    int a = 10;    
    return a;    // a作为局部变量,在栈区 ,函数运行完即销毁,这里仍返回
}
int main()
{

    int& ref1 = test01();
    cout << "ref= " << ref1 << endl; // 第一次编译器做了保留,仍能打印
    cout << "ref= " << ref1 << endl; // 第二次即销毁 
}
②作为函数左值
int& test02()
{
    static int a = 10;
    return a;    // a作为静态变量,在全局区,程序运行完由系统释放
}
int main()
{
    int& ref2 = test02();
    cout << "ref= " << ref2 << endl;  
    cout << "ref= " << ref2 << endl;
    cout << "ref= " << ref2 << endl; // a在静态区,无论打印多少次,数据都存在
    cout << "ref= " << ref2 << endl; 

    test02() = 1000;    // 函数作左值,返回引用
//等价于 a = 1000; 在原名上直接修改
    cout << "ref= " << ref2 << endl;// 在别名上访问
    cout << "ref= " << ref2 << endl;
    cout << "ref= " << ref2 << endl;
    cout << "ref= " << ref2 << endl;
}
  1. 引用的本质

本质:在C++内部,引用的实现即一个指针常量
例①
int main()
{
    int a = 101;

    int& ref = a;// 这里相当于 int *const ref = &a; 即ref是一个指针
    ref = 202;    // 这里即 *ref = 202; 不过是编译器自动实现解引用*改变a,不需要我们写*
    
    cout << ref << endl;
    cout << a << endl;
    return 0;
}
例②
void func(int& ref) // 相当于 int* const ref = &a;
{
    ref = 303; // ref引用,自动转化为 *ref = 303;
}
int main()
{
    int a = 101;
    func(a);
    cout << a << endl;
    return 0;
}

总结:推荐使用,较为方便

  1. 常量引用

作用:用来修饰形参,防止误操作
在具体的函数形参列表中,可以加上const以防止形参改变实参
①例

对于这两段代码是可行的

    int a = 10;    // 先创建变量 a ,再对a引用
    int& ref1 = a;

而这个不可行

    int& ref2 = 20; // 直接引用一串数字 20

引用需要一块合法的内存空间

而在此基础上,加上const

    const int& ref3 = 30;
    // 相当于 int tmp = 30; const int& ref3 = tmp;

此时的ref3是一个临时空间,我们无法直接访问,因此无法再修改

②具体的使用场景
void Print(int& ref)
{
    cout << "a= " <<ref<< endl;
}
int main()
{

    int a = 10;
    Print(a);
}

对于这样一个打印函数,引用作函数参数,正常情况下,打印a的数据

但是,如果在函数内加上赋值

void Print(int& ref)
{
    ref = 20; // 不小心赋值
    cout << "a= " <<ref<< endl;
}

则将改变a的值,而该函数只为了实现打印功能而不是修改,这就造成误操作

因此,在引用上加const

void Print(const int& ref)
{
    ref = 20;
    cout << "a= " <<ref<< endl;
}

直接报错,编译不通过,这就实现了防止误操作的功能

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++之 引用(refer) 的相关文章

  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 赋值运算符和复制构造函数有什么区别?

    我不明白C 中赋值构造函数和复制构造函数之间的区别 是这样的 class A public A cout lt lt A A lt lt endl The copy constructor A a b The assignment cons
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • 开启WSL之旅

    专业点的计算机使用者 会经常跟Linux与windows系统打交道 经常是一台计算机装双系统或者在一个系统中安装虚拟机 双系统来回切换 挺麻烦 遇到同时需要两个环境时 就没办法了 虚拟机 对于配置高的机器还可以 不过性能体验也不太好 总之是
  • “烧钱”的大模型:初探成本拆解与推理优化方法

    编者按 大模型的成本问题一直以来是大家重点关注的问题 本文重点讨论了训练大型语言模型 LLMs 需要的成本 并简要介绍什么是LLM以及一些用于优化大模型推理表现的技术 虽然很难准确预测LLMs未来会怎么发展 但可以肯定 如果成本问题得到解决
  • 服务器系统文件共享如何设置,服务器操作系统文件共享设置

    服务器操作系统文件共享设置 内容精选 换一换 切换操作系统是为您的云服务器重新切换一个系统盘 切换完成后云服务器的系统盘ID会发生改变 并删除原有系统盘 如果云服务器当前使用的操作系统不能满足业务需求 如软件要求的操作系统版本较高 您可以选
  • 思科设备命令讲解(超基础)

    作者 小刘在C站 个人主页 小刘主页 每天分享云计算网络运维课堂笔记 努力不一定有回报 但一定会有收获加油 一起努力 共赴美好人生 夕阳下 是最美的绽放 树高千尺 落叶归根人生不易 人间真情 目录 一 静态路由配置命令 二 默认路由配置命令
  • 2023年前端面试题总结

    某多多 1 Promise实现原理 2 vue组件间通信 3 性能优化 4 vuex数据流动过程 5 谈谈css预处理器机制 6 算法 Promise串行 某眼电影 1 vue组件间通信 2 react和vue更新机制的区别 3 Vue3
  • 超硬货,大型 Rust 项目经验分享

    本篇文章中 我将分享我组织大型 Rust 项目的经验 但这绝不是权威的 只是我通过尝试和错误中发现的一些小技巧 Cargo 作为 Rust 的构建系统 遵循约定大于配置的原则 它不仅为小型项目提供了一套良好的默认配置集 尤其为公共 crat
  • Flash学习笔记

    快捷键 1 F8 可以将散件转化为元件 2 Ctrl 2 满画布显示 3 F6 插入关键帧 4 Ctrl Enter 预览 一 第一章 1 颜料桶 更改填充色 墨水瓶 改变边框色 2 动画的分类 位移动画 形变动画 逐帧动画 路径动画 蒙版
  • Windows server 2012_R2 无法安装VMware Tools解决方法(详细)

    百度网盘 链接 https pan baidu com s 1QbIHSv1Df8eVAIH2ym1g8Q pwd rdi4 提取码 rdi4 官网下载链接 KB2919442https www microsoft com zh cn do
  • Table固定表头固定左侧列

    效果图 思路 把需要固定的内容进行拆封 比如左侧的表头和内容 右侧的表头和内容 都单独的存放在一个table中 在滚动条滚动的时候通过jquery scroll 区分横向纵向滚动条的方法来实现左侧内容的滚动和右侧表头的滚动 第一步 div
  • 直接线性变换解法(DLT)用于标定相机

    直接线性变换法是建立像点坐标和相应物点物方空间坐标之间直接的线性关系的算法 特点 不需要内外方位元素 适合于非量测相机 满足中 低精度的测量任务 可以标定单个相机 1 各坐标系之间的关系推导直接线性变换解法 1 1 像素坐标系与像平面坐标系
  • MATLAB中用Application Complier生成可执行文件的步骤及相关注意事项

    生成可独立执行的软件 可以分成以下5个主要的步骤 1 打开Application Complier 2 添加主程序文件 3 可执行文件设置 4 选择打包方式 5 相关文件解释 大体步骤多类似 里面有些容易出错的小细节 相关设置需要注意的有
  • node中使用express+mongodb实现分页查询

    文章目录 引言 一 分页案例 二 查询方法扩展介绍 1 find 2 limit 3 skip 4 populate 总结 引言 在Web应用程序开发中 分页查询是必不可少的功能之一 Node js提供了许多优秀的工具和框架来实现分页查询
  • 马虎的算式

    import java util public class Main public static void main String args int ans 0 for int a 1 a lt 10 a for int b 1 b lt
  • Struts2输入校验(XML方式)

    本章主要介绍struts2的XML配置方式输入校验 以下将结合一个实例程序进行说明 代码结构 关键代码 RegistAction javapackage com alfred regist action import java util D
  • libuv 高并发异步使用

    问题来源 在开发libuv客户端 服务器时 需要并发的向客户端发送数据 libuv就会用到 uv write函数 因此 我的初步方案是 1 创建线程池 2 线程池分配数据内存buf 并打包 3 将包发给 uv write 4 uv writ
  • 为什么越来越多的企业选择云数据存储而放弃本地数据存储?

    随着企业的发展 它们会产生大量数据 企业已经意识到 利用他们的数据做出数据驱动的决策对于创新和保持竞争优势至关重要 本文将会探讨企业在收集和分析大数据时可能面临的主要挑战 以及将企业数据仓库部署到本地或云数据存储的选择 我们将根据安全性 成
  • 金融行业软件测试

    金融行业软件测试 一 什么是金融行业 二 金融行业的业务特点 1 金融行业的业务特点 三 金融行业测试主要测试范围 1 功能测试 2 业务验证测试 3 客户端测试 4 接口测试 5 性能测试 6 安全性测试 四 金融行业软件测试的现状 五
  • Qt-Web混合开发-QWebEngineView加载网页最小示例(1)

    Qt Web混合开发 QWebEngineView加载网页最小示例 文章目录 Qt Web混合开发 QWebEngineView加载网页最小示例 1 概述 2 实现效果 3 实现功能 4 关键代码 5 源代码 更多精彩内容 个人内容分类汇总
  • docker原理及服务编排

    一 什么是docker Docker 是一个开源项目 诞生于2013年初 最初是dotCloud公司内部的一个业余项目 它基于Google公司推出的Go语言实现 项目后来加入了Linux基金会 遵从了Apache 2 0协议 项目代码在Gi
  • C++之 引用(refer)

    含义 变量的别名 第二名称 作用 使用别名访问原名的内存空间 即别名与原名保存同样的内存空间 语法 数据类型 别名 原名 int b a 注意事项 引用必须要初始化 对于一个变量a 不能直接写int b 而需要写int b a 引用在初始化