[c++]实例观察返回值优化

1 返回值优化现象 RVO

如下代码,在 MakeObj() 中创建了一个局部对象 obj,并将 obj 返回。 Test() 函数调用了 MakeObj(),并将 MakeObj() 的返回值赋值给了 obj。

按我们的预期,MakeObj() 是值返回,在 main() 调用 Test() 的过程中,应该发生了两次构造和两次析构。

第一次构造:默认构造,在 MakeObj() 声明局部变量的时候。

第二次构造:拷贝构造,在 MakeObj() 返回的时候,将返回值赋值给 Test() 中的局部变量 obj 时

第一次析构:在函数 Test() 中,MakeObj() 返回值赋值给 Test() 中的 obj 完成时, MakeObj() 中的局部变量析构

第二次析构:在函数 Test() 返回时,Test() 函数中的 obj 析构

#include <iostream>class Obj {
public:Obj(int i) {i_ = i;std::cout << "Obj(), i: " << i_ << ", this: " << this << std::endl;}Obj(const Obj &obj) {i_ = obj.i_;std::cout << "copy constructor, i: " << i_ << ", this: " << this << std::endl;}~Obj() {std::cout << "~Obj(), i: " << i_ << ", this: " << this << std::endl;}int i_;};Obj MakeObj() {int a = 10;Obj obj(1);int b = 10;printf("1, &obj = %p, &a = %p, &b = %p, sizeof(obj) = %d\n", &obj, &a, &b, sizeof(obj));return obj;
}void Test() {printf("before make obj\n");int a = 100;Obj obj = MakeObj();int b = 100;printf("2, &obj = %p, &a = %p, &b = %p\n", &obj, &a, &b);printf("after make obj\n");
}int main() {Test();printf("before main return\n");return 0;
}

编译之后运行,现象与我们预期的并不是一致的。如下图所示,只发生了一次构造和一次析构。

并且在 MakeObj() 和 Test() 中均把 obj 的地址打印出来了,两个对象的地址是一样的。

2 禁用返回值优化:-fno-elide-constructors

g++ 编译的时候,默认开启了返回值优化,如果想要禁用返回值优化,那么在编译时需要带上标志 -fno-elide-constructors。

如下图所示,禁用返回值优化之后,运行过程与我们预期的是一致的。

 

3 局部变量在函数返回的时候没有销毁吗

从上边的实验可以看出,默认情况下,编译器开启了返回值优化。但是从常识来看,函数返回的时候,局部变量(栈空间)要释放,对象会销毁。

那么开启返回值优化的时候,函数返时,难道局部对象没有销毁 ? 

开启返回值优化的时候,并没有违反栈销毁的规律。

从上边的打印结果可以看出来,在函数 MakeObj() 以及 Test() 函数中,局部变量 obj 前后分别定义了局部变量 a 和 b,把 a 和 b 的地址也打印出来了。

局部变量都是保存在栈上,一个函数中的多个局部变量的地址应该是相邻的才对。但是看打印结果,obj 的地址和 MakeObj() 中的 a 和 b 的地址并不是相邻的,而是和 Test() 中的 a 和 b 是相邻的。这就是编译器起的作用,编译器判断变量的生命周期,然后决定将局部变量放在哪个位置。

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

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

相关文章

2.1tarjian算法求解双连通分量

P2860 [USACO06JAN] Redundant Paths G 就是说通过加边&#xff0c;使得图中的每一点都不是割点&#xff0c;就是让连通图中没有桥&#xff0c;没有割点 并非是桥的数量-1 边双连通分量即一个无向图中&#xff0c;去掉一条边后仍互相连通的极大子图。&#xff08;单独的一个…

基于编译器的静态代码分析与软件开发效率、质量和性能

基于编译器的静态代码分析与软件开发效率、质量和性能 本文节选自《基础软件之路&#xff1a;企业级实践及开源之路》一书&#xff0c;该书集结了中国几乎所有主流基础软件企业的实践案例&#xff0c;由 28 位知名专家共同编写&#xff0c;系统剖析了基础软件发展趋势、四大基…

袁庭新ES系列10节 | 使⽤kibana对⽂档操作

前言 在前面的小节中&#xff0c;我们已经给大家介绍了Elasticsearch中文档的相关概念&#xff0c;想必有些同学都已经忘记了&#xff0c;那我们一块儿再来回顾下&#xff0c;文档即索引库中某个类型下的数据&#xff0c;会根据规则创建索引&#xff0c;将来用来搜索。可以类比…

HTML+CSS:动态搜索框

效果演示 这段代码实现了一个简单的搜索栏效果。页面背景为从天蓝色到深蓝色的渐变色&#xff0c;搜索栏包括一个圆形背景的搜索图标和一个输入框。当用户点击搜索图标时&#xff0c;输入框会从搜索图标的位置滑出&#xff0c;显示一个输入框和一个清除按钮。用户可以在输入框中…

Unity(第三部)新手绘制地形

1、创建地形 游戏对象3d对象地形 2、功能 1、 红框内按键为创建相邻地形、点击后相近地形会呈现高亮框、点击高亮区域可以快速创建地形 每块地形面积是1km*1km 2、第二个按钮是修改地形 下面的选择是修改类型 选项含义描述Raise or Lower Terrain升高或降低地形单击左键可…

pikachu靶场-File Inclusion

介绍&#xff1a; File Inclusion(文件包含漏洞)概述 文件包含&#xff0c;是一个功能。在各种开发语言中都提供了内置的文件包含函数&#xff0c;其可以使开发人员在一个代码文件中直接包含&#xff08;引入&#xff09;另外一个代码文件。 比如 在PHP中&#xff0c;提供了&…

5G网络(接入网+承载网+核心网)

5G网络&#xff08;接入网承载网核心网&#xff09; 一、5G网络全网架构图 这张图分为左右两部分&#xff0c;右边为无线侧网络架构&#xff0c;左边为固定侧网络架构。 无线侧&#xff1a;手机或者集团客户通过基站接入到无线接入网&#xff0c;在接入网侧可以通过RTN或者IP…

如何在Linux Ubuntu系统使用Docker快速部署MongoDB并公网访问

文章目录 前言1. 安装Docker2. 使用Docker拉取MongoDB镜像3. 创建并启动MongoDB容器4. 本地连接测试5. 公网远程访问本地MongoDB容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Linux Ubuntu系统使用Docker快速部署Mon…

互联网加竞赛 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#x…

8.qt5使用opencv的库函数打开图片

1.配置opencv动态库的环境变量 2.在创建的qt工程中加入如下opencv代码&#xff0c;具体代码如下&#xff1a; 使用opencv库函数显示图片

Linux进一步研究权限-----------ACL使用

一、使用情况 1.1、场景: 某个大公司&#xff0c;在一个部门&#xff0c;有一个经理和手下有两个员工&#xff0c;在操控一个Linux项目,项目又分为三期做&#xff0c;然而一期比较重要&#xff0c;经理带着员工做完了&#xff0c;公司就觉得技术难点已经做完攻克了&#xff0…

【自然语言处理-二-attention注意力 是什么】

自然语言处理二-attention 注意力机制 自然语言处理二-attention 注意力记忆能力回顾下RNN&#xff08;也包括LSTM GRU&#xff09;解决memory问题改进后基于attention注意力的modelmatch操作softmax操作softmax值与hidder layer的值做weight sum 计算和将计算出来的和作为memo…

《Python 语音转换简易速速上手小册》第1章 Python语音处理概述(2024 最新版)

文章目录 1.1 语音处理的基础1.1.1 基础知识1.1.2 主要案例:自动语音识别系统案例介绍案例 Demo案例分析1.1.3 扩展案例 1:智能虚拟助手案例介绍案例 Demo案例分析1.1.4 扩展案例 2:情感分析系统案例介绍案例 Demo

NATS学习笔记(一)

NATS是什么&#xff1f; NATS是一个开源的、轻量级、高性能的消息传递系统&#xff0c;它基于发布/订阅模式&#xff0c;由Apcera公司开发和维护。 NATS的功能 发布/订阅&#xff1a;NATS的核心是一个发布/订阅消息传递系统&#xff0c;允许消息生产者发布消息到特定的主题…

2024生物发酵魅力展示会-光德流体

参展企业介绍 河北光德流体控制有限公司始建于1996年&#xff0c;是一家从事以不锈钢为母材的洁净应用材料研发与专业制造的实体企业。产品主要包括卫生级球阀&#xff0c;隔膜阀&#xff0c;蝶阀等&#xff0c;并广泛应用于生物发酵&#xff0c;医疗制药&#xff0c;食品饮料…

初识51单片机

##江科大51单片机学习 什么是单片机&#xff1f;&#xff1f;&#xff1f; 单片机&#xff0c;英文名&#xff0c;Micro Controller Unit&#xff0c;简称MCU&#xff08;tips&#xff1a;有人会简称它为CPU&#xff0c;但不是如此&#xff0c;CPU其实被集成在MCU中&#xff…

视频评论抓取软件|抖音数据抓取工具

最近我们推出了一款基于C#语言开发的工具。这款工具提供了丰富的功能&#xff0c;旨在帮助用户轻松获取抖音视频内容。让我们一起来详细介绍一下这款工具的主要功能模块&#xff1a; 1. 批量视频提取&#xff1a; 工具提供了便捷的批量视频提取功能&#xff0c;用户只需输入关…

第3部分 原理篇2去中心化数字身份标识符(DID)(3)

3.2.2.4. DID文档 (DID Document) 本聪老师&#xff1a;DID标识符和DID URL还都只是ID&#xff0c;必须为它附加一个基本属性才可以证明是该主体独有的。这个就是我们下面介绍的DID文档。 本聪老师&#xff1a;每个DID标识符都唯一对应一个DID文档&#xff0c;也可以说&#x…

潇洒郎:2024 IDEA、Pycharm获取最新激活码获取方式

IDEA获取最新激活码 https://idea.javatiku.cn/ 手机打开&#xff0c;看到验证码&#xff0c;30分钟有效&#xff0c;输入验证码 获取到最新激活码

Redis(十六)缓存预热+缓存雪崩+缓存击穿+缓存穿透

文章目录 面试题缓存预热缓存雪崩解决方案 缓存穿透解决方案 缓存击穿解决方案案例&#xff1a;高并发聚划算业务 总结表格 面试题 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况?缓存预热你是怎么做的?如何避免或者减少缓存雪崩?穿透和击穿有什么区别?他两是…