C++对象模型(16)-- 构造函数语义学:临时对象

news2024/11/19 13:37:18

临时对象是栈上的没有名字的对象,它在源码中是不可见的,是编译器偷偷摸摸在背后干的。

比如下面的代码就会产生临时对象:

int i = 1;

// 这里的 i++ 会产生临时对象,这里的临时对象是在系统中产生,代码中看不见的
// 首先将i的值赋给临时对象,再把临时对象的值作为返回结果赋给j,再对i进行自增操作。
int j = i++;

临时对象有以下几个特点:

(1)临时对象是在栈上生成的。

(2)临时对象是右值,可通过“const 左值引用”绑定临时对象,或通过右值绑定临时对象。

(3)临时对象的产生和销毁会调用1次构造函数和析构函数。

临时对象的产生和销毁需要消耗系统资源,所以在写代码时应尽量避免临时对象的产生。

1、临时对象的产生及解决办法

临时对象主要产生在下列场景中:

(1)在栈中生成无名对象时

Integer objI = Integer(1);

先产生一个Integer临时对象,然后调用拷贝构造函数生成objI对象。

解决办法:在定义时直接初始化。

Integer objI(1);
Integer objI{1};

(2)类型转换

class MyDemo {
public:
    MyDemo(){}

    MyDemo(int i) {
        std::cout << "构造函数MyDemo(int i)" << std::endl;
    }

    MyDemo& operator = (const MyDemo& _demo) {
        std::cout << "赋值运算符" << std::endl;
        
        return *this;
    }

    ~MyDemo() {
        std::cout << "析构函数" << std::endl;
    }
};

int main()
{

    MyDemo demo;
    demo = 100;

    return 0;
}

这里的demo = 100,会产生临时对象:

(1)将 100为参数调用了MyDemo的构造函数创建了一个临时对象;

(2)通过拷贝赋值运算符,将临时对象的成员值赋给了demo;

(3)销毁临时对象。

解决办法:创建对象时进行初始化。

MyDemo demo = 100;

(3)隐式类型转换

void testFunc(const MyDemo& demo) {}

int main()
{
    int i = 2;
    testFunc(i);
    
    return 0;
}

上面的testFunc(i),会产生临时对象。int值会先转换成MyDemo类型的临时对象,然后赋值给形参demo。

解决办法:

将传入的实参和函数的形参类型保持一致即可:

testFunc(MyDemo(i));

(4)函数参数

函数的参数传值是值传递,在函数调用时系统会创建一个临时对象。

class MyDemo {
public:
    MyDemo() {}

    MyDemo(int i) {
        std::cout << " 构造函数MyDemo(int i)" << std::endl;
    }

    MyDemo(const MyDemo& _demo) {
        std::cout << " 拷贝构造函数" << std::endl;
    }

    ~MyDemo() {
        std::cout << " 析构函数" << std::endl;
    }
};

void testFunc(MyDemo demo) {
    std::cout << " testFunc" << std::endl;
}

int main()
{
    MyDemo demo;
    testFunc(demo);
    
    return 0;
}

从执行结果可以看到,在调用testFunc()函数时,指向了拷贝构造函数。

解决办法:把值传递改成引用传递。

void testFunc(MyDemo& demo) {}

(5)函数返回值

在函数返回对象时候,会创建一个临时对象接收这个对象;从而调用了拷贝构造函数,和析构函数。

MyDemo testFunc() {
    MyDemo demo;

    return demo;
}

int main()
{
    MyDemo demo = testFunc();

    return 0;
}

解决办法:

(1)修改testFunc的形参,把返回对象作为形参传入函数。

MyDemo testFunc(MyDemo& ret) {}

(2)用右值接收返回值

MyDemo&& d = testFunc();

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

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

相关文章

Deep Joint Demosaicking and Denoising

Abstract 去马赛克和去噪是数字成像流程的关键第一阶段&#xff0c;但它们也是一个严重不适定的问题&#xff0c;从单个噪声测量中推断出每个像素的三个颜色值。早期的方法依赖于手工制作的滤波器或先验&#xff0c;并且在硬情况下&#xff08;例如摩尔纹或薄边缘&#xff09;…

Bootstrap的导航栏设计相关知识

Bootstrap的导航栏设计相关知识 目录 01-基础知识02-最基本的导航栏设计例子03-带下拉菜单的导航04-在导航栏中添加表单元素05-固定导航栏的位置(如固定到顶部和底部)06-设计导航栏的颜色和文本颜色 01-基础知识 导航栏是网页设计中不可缺少的部分&#xff0c;它是整个网站的…

ABB变频器使用PROFINET IO通信模块时的激活方法

ABB变频器使用PROFINET IO通信模块时的激活方法 ABB传动通讯总线适配器的激活(ACS380): 首先,如下图所示,要采购并安装PROFINET IO总线通信模块(我这里支持3种通信协议,大家在实际使用时,用到哪种就购买哪种即可), 如下图所示,进入参数设置, 如下图所示,进入“完…

如何使用Python抓取PDF文件并自动下载到本地

目录 一、导入必要的库 二、发送HTTP请求并获取PDF文件内容 三、将PDF文件内容写入到本地文件中 四、完整代码示例 五、注意事项 六、错误处理和异常处理 七、进一步优化 总结 在Python中&#xff0c;抓取PDF文件并自动下载到本地需要使用几个不同的库。首先&#xff0…

EV SSL数字证书贵吗

EVSSL证书通常适用于具有高需求的网站和企业&#xff0c;特别是涉及在线交易、金融服务、电子商务平台等需要建立用户信任的场景。大型企业、金融机构、电子商务平台等可以受益于使用EV证书来提升品牌形象和安全性。 申请EVSSL证书&#xff08;Extended Validation SSL certifi…

复制粘贴(二):操作剪贴板 navigator.clipboard

使用 navigator.clipboard 可以随时获取剪贴板对象&#xff08;也就是说&#xff0c;在 copy/paste 事件外也可以用&#xff09; 但是&#xff0c;此操作必须用户允许&#xff1a; readText readText() 获取剪贴板中的文本内容 <!DOCTYPE html> <html><head&…

java: 错误: 无效的源发行版:17

原因分析&#xff1a; 这个错误表明你的Java开发环境不支持Java 17的源发行版。这可能是因为你的JDK&#xff08;Java Development Kit&#xff09;版本过低&#xff0c;不支持Java 17的特性。 以下是解决此问题的一些步骤&#xff1a; 检查你的JDK版本&#xff1a;在命令行…

java影院管理信息系统设计参考学习

系统设计&#xff1a; 1.1功能结构 为了更好的去理清本系统整体思路&#xff0c;对该系统以结构图的形式表达出来&#xff0c;设计实现该影院系统的功能结构图如下所示&#xff1a; 图1-1 系统总体结构图 1.2数据库设计 1.2.1数据库E/R图 ER图是由实体及其关系构成的图&…

易点易动设备管理系统帮助生产企业提升设备维修效率

在现代制造业中&#xff0c;设备的正常运行对于生产企业的成功至关重要。然而&#xff0c;设备故障和维修工作常常成为生产过程中的瓶颈&#xff0c;影响生产效率和利润。为了解决这个问题&#xff0c;许多企业采用了现代化的设备管理系统&#xff0c;其中易点易动设备管理系统…

智能管家“贾维斯”走进现实?AI Agent或成2023科技领域新风向标

漫威粉们想必都知道《钢铁侠》系列电影中&#xff0c;有一个不可或缺的角色——贾维斯。但就算是没有看过任何一部大电影的路人&#xff0c;只要通过一个词就可以了解“贾维斯”是一个什么样的角色——智能管家。 作为托尼斯塔克的助手&#xff0c;贾维斯的存在让主人的生活更…

分享40个Python游戏源代码总有一个是你想要的

下载链接&#xff1a;https://pan.baidu.com/s/1bwj2GQM1CbO1x2EIC-ZF6g?pwd8888 提取码&#xff1a;8888 项目名称&#xff1a; Chinese Chess Xiangqi 中国象棋 Python Python 图形化麻将游戏 (带蒙特卡洛AI) python做的一个足球小游戏 python做的坦克大战游戏 py…

【R】数据相关性的可视化

一千零一技|相关性分析及其可视化&#xff1a;copy&paste&#xff0c;搞定 .libPaths(c("/bioinfo/home/software/miniconda3/envs/R4.0/lib/R/library")) #data("mtcars") library("PerformanceAnalytics") # pdf("test.pdf") #…

前端开发调试技巧:如何在Component下选中当前插件并且查看当前插件信息

在react开发项目中&#xff0c;在Component下选中组件&#xff0c;然后在控制台输$r 按回车键即可输出该组件信息。例如 $r.props输出该组件的props参数。例子详情见如下截图

使用canvas实现图片轮播抽奖效果,轮播速度由慢到快,然后再到慢

整体的效果就是中间的那张图片会连续不断地切换&#xff0c;我部署到github上面了&#xff0c;可以点击链接试一试&#xff1a;canvas在线抽奖系统效果 附上源代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-…

【C++那些事儿】初识C++ 命名空间,C++中的输入输出以及缺省函数

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;数据结构和算法初阶更新完毕&#xff0c;我们继续来扩充我们的知识面&#xff0c;今天我们从认识C开始来带大家学习C&#xff0c;我之前看过一套…

半导体测试方法主要有哪几种?

外观检测&#xff1a;对半导体外观质量的评估&#xff0c;包括检查芯片的平整度、颜色、镜面度等。 电性能测试&#xff1a;测量半导体的电导率、电阻率、电流和电压特性等&#xff0c;以评估其电性能。 温度测试&#xff1a;用于测量半导体在不同温度下的电性能表现&#xf…

软件测试过程中如何有效的开展接口自动化测试

一.简介 接口自动化测试是指使用自动化测试工具和脚本对软件系统中的接口进行测试的过程。其目的是在软件开发过程中&#xff0c;通过对接口的自动化测试来提高测试效率和测试质量&#xff0c;减少人工测试的工作量和测试成本&#xff0c;并且能够快速发现和修复接口错误&…

37 WEB漏洞-反序列化之PHPJAVA全解(上)

目录 PHP反序列化演示案例&#xff1a;先搞一把PHP反序列化热身题稳住-无类问题-本地在撸一把CTF反序列化小真题压压惊-无类执行-实例最后顶一把网鼎杯2020青龙大真题舒服下-有类魔术方法触发-实例 https://www.cnblogs.com/zhengna/p/15661109.html 代码在线测试平台&#xff…

相机镜头选择与机器视觉控制

相机镜头选择与机器视觉控制 在机器视觉领域&#xff0c;除了图像处理和算法&#xff0c;还需要关注硬件方面的选型和控制。相机镜头的选择是其中重要的一部分&#xff0c;需要考虑像素大小、镜头焦距等因素以满足项目需求。此外&#xff0c;编程技能也包括相机的调用和使用&a…

django建站过程(1)

django建站过程&#xff08;1&#xff09; 使用pycharm创建过程运行项目创建数据库创建超级用户登录生成的后台&#xff1a;界面本地化 准备以django,bootstrap来做一个过程记录&#xff0c;文章主要阐述过程的细节。 使用pycharm创建过程 创建项目“schoolapps”&#xff0c;…