C++中函数返回值是一个对象时的问题(转)
时间:2020-03-27
本文章向大家介绍C++中函数返回值是一个对象时的问题(转),主要包括C++中函数返回值是一个对象时的问题(转)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
原文链接:https://www.cnblogs.com/yanhai307/p/10935665.html
参考链接:
https://www.cnblogs.com/mini-coconut/p/8542560.html
https://www.cnblogs.com/ysherlock/p/7822287.html
问题描述
在C++程序中,一个函数返回值是一个对象时,返回的是函数内部的局部变量本身,
还是会产生一个中间对象(匿名对象)呢?
经过测试,在win平台和Linux平台效果不同
代码如下
// // Created by YANHAI on 2019/5/28. // #include <iostream> using namespace std; class Test { public: Test(const char *name) { this->name = name; printf("%s: 执行了构造函数, 我的地址是 %p\n", name, this); } Test(const Test &obj) { this->name = obj.name; printf("%s: 执行了拷贝构造函数,我的地址是 %p,拷贝来自%s %p\n", name.c_str(), this, obj.name.c_str(), &obj); } ~Test() { printf("%s: 执行了析构函数, 我的地址是 %p\n", name.c_str(), this); } public: string name; }; Test fun() { Test t("我是在fun函数中创建的"); printf("in fun: %p\n", &t); return t; } void test1() { // 这里t1对象就是fun函数里面创建的? cout << "fun start.." << endl; Test t1 = fun(); cout << "fun end.." << endl; t1.name = "我是在test函数中被创建的"; printf("我是在test函数中被创建的对象,我的地址是: %p\n", &t1); } int main() { cout << "--------test1 start ...-----" << endl; test1(); cout << "--------test1 end ...-----" << endl; return 0; }
测试过程
在win平台
使用VS2019编译并运行
运行结果:
--------test1 start ...----- fun start.. 我是在fun函数中创建的: 执行了构造函数, 我的地址是 010FFAC4 in fun: 010FFAC4 我是在fun函数中创建的: 执行了拷贝构造函数,我的地址是 010FFBD4,拷贝来自我是在fun函数中创建的 010FFAC4 我是在fun函数中创建的: 执行了析构函数, 我的地址是 010FFAC4 fun end.. 我是在test函数中被创建的对象,我的地址是: 010FFBD4 我是在test函数中被创建的: 执行了析构函数, 我的地址是 010FFBD4 --------test1 end ...-----
过程解释:
- 在fun函数中,t对象被创建,执行t对象的构造函数(t对象地址为 010FFAC4)
- 在fun函数执行return时,会产生一个匿名对象,会执行匿名对象的拷贝构造函数,相当于执行了 Test tmp = t; (匿名对象tmp地址为010FFBD4)
- fun函数执行结束,局部变量对象t被释放,执行t对象的析构函数,fun函数将匿名对象(tmp)返回(返回的是010FFBD4地址的匿名对象)
- 在test1函数中,t1对象被创建时 使用了fun函数的返回值,故匿名对象tmp直接变为t1对象(而不是执行拷贝构造函数给t1,就比如执行了Test t1 = Test("xx");)(t1对象的地址即为匿名对象地址 010FFBD4)
- test1函数执行完毕后,t1对象被释放,执行t1的析构函数
在linux平台
使用g++编译
运行结果:
--------test1 start ...----- fun start.. 我是在fun函数中创建的: 执行了构造函数, 我的地址是 0x7ffe5a2488c0 in fun: 0x7ffe5a2488c0 fun end.. 我是在test函数中被创建的对象,我的地址是: 0x7ffe5a2488c0 我是在test函数中被创建的: 执行了析构函数, 我的地址是 0x7ffe5a2488c0 --------test1 end ...-----
过程解释:
- 在fun函数中,t对象被创建,执行t对象的构造函数(t对象地址为 0x7ffe5a2488c0)
- 在fun函数结束时,并没有产生匿名对象,而是将t对象返回(返回的是0x7ffe5a2488c0地址的对象t)
- 在test1函数中,t1对象被创建时 使用了fun函数的返回值,故返回对象t直接变为t1对象(而不是执行拷贝构造函数给t1,就比如执行了Test t1 = Test("xx");)(t1对象的地址即为t对象地址 0x7ffe5a2488c0)
- test1函数执行完毕后,t1对象被释放,执行t1的析构函数
结论
- 在linux平台上,少产生了一个匿名对象,提高了执行效率
- 原本仅在fun函数内有效(局部变量生存周期)的t对象,由于被返回,在test1函数中仍然有效
原文地址:https://www.cnblogs.com/lh03061238/p/12580907.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ES UpdateByQuery Java Api
- [Bazel]repository_rule() vs rule()
- Windows 系统信息收集姿势
- 小白学PyTorch | 3 浅谈Dataset和Dataloader
- 小白学PyTorch | 4 构建模型三要素与权重初始化
- 小白学PyTorch | 5 torchvision预训练模型与数据集全览
- 细品redis的Scan和Keys命令
- if语句与while语句
- 内网渗透 | 基于IPC的横向移动
- 【DB笔试面试866】队列等待之enq: TX - allocate ITL entry
- 【Vue.js】Vue.js组件库Element中的上传、评分、穿梭框和表单
- 【Vue.js】Vue.js项目构建
- 【Vue.js】Vue.js组件库Element中的表格、标签和进度条
- 用个小技巧,趁你不备,rm -rf你的电脑
- 什么是Python 中的EAFP 哲学