#include<iostream>
using namespace std;
typedef struct dong
{
int a[4];
}Dong;
typedef struct dong2
{
int b;
}Dong2;
typedef struct dong3
{
int a;
int b;
}Dong3;
class Dong4
{
public:
int a;
};
class Dong5
{
public:
int a;
int b;
};
class Dong6
{
public:
int age;
Dong6(){}
};
class Dong7
{
public:
int a[4];
};
class Dong8
{
public:
int a[4];
Dong8(){}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Dong test()
{
Dong d;
d.a[0] = 1;
return d;
}
Dong2 test2()
{
Dong2 d2;
d2.b = 6;//00F851CE mov dword ptr [d2],6
return d2;//000A51D5 mov eax,dword ptr [d2] 返回值使用eax带出来的
}
Dong3 test3()
{
Dong3 d3;
d3.a = 2;//00B93ACE mov dword ptr [d3],2
d3.b = 6;//00B93AD5 mov dword ptr [ebp-8],6
return d3;
/*
00B93ADC mov eax,dword ptr [d3]
00B93ADF mov edx,dword ptr [ebp-8] 用了 eax 和 edx 把返回值带出去
*/
}
Dong4 test4()
{
Dong4 d4;
d4.a = 10;
return d4;//00B75235 mov eax,dword ptr [d4] 同上
}
Dong5 test5()
{
Dong5 d5;
d5.a = 10;
d5.b = 20;
return d5;
/*
011A533C mov eax,dword ptr [d5]
011A533F mov edx,dword ptr [ebp-8] 同上
*/
}
Dong6 test6()
{
Dong6 d6;
d6.age = 20;
return d6;
}
Dong7 test7()
{
Dong7 d7;
d7.a[0] = 1;
return d7;
}
Dong8 test8()
{
Dong8 d8;
d8.a[0] = 5;
return d8;
}
void main2()
{
Dong d = test();
/*
011F7F6E lea eax,[ebp-104h]
011F7F74 push eax 形参入栈
011F7F75 call test (011F13A7h) 在调用之前,在main中开辟了内存,产生了临时对象,并把临时对象的地址传到test()函数中
*/
Dong2 d2 = test2();
/*
013A7FC4 call test2 (013A1429h) 在调用之前没有压栈,也就是没有参数传递
*/
Dong3 d3 = test3();
/*
00FA8038 call test3 (0FA142Eh) 同上
*/
Dong4 d4 = test4();
/*
00D680BB call test4 (0D61433h) 同上
013D612A mov dword ptr [ebp-138h],eax
013D6130 mov eax,dword ptr [ebp-138h]
013D6136 mov dword ptr [d4],eax
和d6的区别在于,默认构造函数可以把值带出来进行赋值,自定义构造函数编译器不知道我们做了什么,所以不能这样做
*/
Dong5 d5 = test5();
/*
011A812F call test5 (011A1438h) 同上
*/
Dong6 d6 = test6();
/*
010C615C lea eax,[d6]
010C615F push eax 我还以为创建了临时对象,结果仔细一看不对,它只是把指向d6内存指针给压栈了,传进去了,目的,节约内存,直接在函数中进行构造
010C6160 call test6 (010C101Eh) 相当于 Dong6 d6 = d6 等价于 Dong6 d6(d6)
和d4的区别在于,d6有自定义的构造函数,需要调用自己的构造函数
*/
Dong7 d7 = test7();
/*
00A16418 lea eax,[ebp-14Ch] 发现和d6的区别了么???? 这里创建了临时对象
00A1641E push eax
00A1641F call test7 (0A114D3h)
*/
Dong8 d8 = test8();
/*
00CB649E lea eax,[d8]
00CB64A4 push eax
00CB64A5 call test8 (0CB14DDh) 和d6一模一样
*/
/*
在这里就可以总结了:当没有自定义构造函数的时候,函数返回一个对象(内存大于8的话)需要在调用函数中创建临时对象
如果有了自定义构造函数,那么直接把d8这个对象地址传进去,在函数里面直接就初始化了,根本不需要带出来,也就不产生临时量
★为什么没有自定义构造,内存大于8会产生临时对象
★定义了构造函数,绝对不会产生临时对象
*/
/*----------------上面试初始化过程--------------------------------下面是赋值过程----------------*/
Dong4 d41; //没有自定义构造函数
d41 = test4();
/*
00D85BFD call test5 (0D81320h)
*/
Dong7 d71; // 和d41比,内存大于8 字节了
d71 = test7();
/*
00AE9BE4 lea eax,[ebp-1B8h]
00AE9BEA push eax
00AE9BEB call test7 (0AE14C4h)
*/
Dong6 d61; // 和d41比,有自定义构造函数
d61 = test6();
/*
00D75C08 lea eax,[ebp-17Ch]
00D75C0E push eax
00D75C0F call test6 (0D7101Eh)
*/
Dong8 d81; //和d61比,内存大于8字节
d81 = test8();
/*
01265C08 lea eax,[ebp-1E4h]
01265C0E push eax
01265C0F call test8 (012612D5h)
*/
/*
★总结:赋值运算,只要有自定义构造,就会产生临时对象,没有自定义构造,大于8字节才会产生临时对象
有自定义构造函数,和没有自定义构造函数的区别:
有自定义构造函数就需要传入这个对象的地址,也就是this指针,如果没有自定义构造函数,也就不需要传this指针,也就不需要这个对象的地址
*/
getchar();
}
/*
最终的总结:初始化过程------基本都不会产生临时量,只有没有构造函数且内存大于8字节才会产生临时量
赋值过程--------基本都会产生临时量, 只有没有构造函数且内存小于8字节才不会产生临时量
*/
相关推荐
华硕ROG玩家国度安装Ubuntu双系统避坑指南:安全启动密钥那些事儿
本文详细解析了在华硕ROG玩家国度设备上安装Ubuntu双系统时,如何正确处理BIOS中的安全启动(Secure Boot)与密钥管理,避免常见的引导失败和Windows系统无法启动问题。指南提供了从数据备份、启动盘制作到BIOS精细设置(如将OS Type改为Other OS而非简单关闭Secure Boot)以及分区规划的完整流程,确保两个系统都能稳定共存。
调用函数返回值值临时变量问题
对于所调用的函数里面的临时变量,在函数调用过程中是被压到程序进程的栈中的,当函数退出时,临时变量出栈,即临时变量已经被销毁,临时变量占用的内存空间没有被清空,但是已经可以被分配给其他变量了,所以有可能在函数退出时,该内存已经被修改了,对于临时变量来说已经是没有意义的值了。 在C中,16bit程序中,返回值保存在ax寄存器中,32bit程序中,返回值保持在eax寄存器中,如果是64bit返回值,...
关于三维全波电磁场仿真软件CST的安装和问题解决
百度网盘链接:https://pan.baidu.com/s/1RgWr8Qau1EzSOlh29SewFQ提取码:fzza这里是2023版本的CST,需要其他版本的uu们可以去官网或者其他人的网盘下载。
浅解返回值式的函数中临时对象的问题
<br />定义类B:<br />定义类B:<br /><br />class B <br />{<br />public:<br /> B()<br /> {<br /> cout<<"B的构造函数"<<endl;<br /> }<br /><br /> B(int i)<br /> {<br /> cout<<"带int型参数的B的构造函数"<<endl;<br /> }<br /><br /> B(B &ano)<br /> {<br /> cout<<"B的复制构造函数"<<endl;<b
从C-EPS到DP-EPS:手把手图解不同EPS类型怎么选,对你的车操控感影响有多大?
方向盘转动时那股细腻的阻尼感,高速过弯时令人安心的沉稳,或是狭窄车位里一根手指就能拨动的轻盈——这些看似微妙的差异,其实都源自转向系统电机那几厘米的安装位置变化。当我们谈论驾驶乐趣时,发动机参数和悬架调校总是占据C位,但真正连接驾驶者与车辆的神经末梢,恰恰是那套默默工作的电动助力转向系统(EPS)。不同EPS类型带来的操控特性差异,可能比马力数字更能定义一辆车的性格。
基于PID的定速巡航控制系统设计【MATLAB源码+Word文档】
本文详细介绍了定速巡航控制是一种车辆驾驶辅助系统,它能让驾驶者在高速或长途驾驶时,设定一个固定的车速,然后车辆会自动维持这个速度行驶,无需驾驶者持续踩油门。这大大减轻了驾驶者的疲劳,同时也提高了行驶的安全性。PID定速巡航控制系统是一种利用比例(Proportional)、积分(Integral)和微分(Derivative)控制算法来实现车辆定速巡航的先进系统。这种系统能够根据设定的速度,自动调整油门开度或制动力度,使车辆保持恒定的速度行驶。这种控制系统具有响应速度快、控制精度高、稳定性好等优点。
函数的返回值和临时对象的问题
在函数的声明时,其实是最重要的一步,如何设计一个好的接口(用户友好),直接决定了后面的编码工作是否能够行云流水。先给出整体架构,检查各类和接口之间的逻辑有没有问题。
Cygwin安装教程
简介 cygwin是一个在windows平台上运行的unix模拟环境,是cygnus solutions公司开发的自由软件 Cygwin就是一个windows软件,该软件就是在windows上仿真linux操作系统 简言之,cygwin是一个在windows平台上运行的 linux模拟环境,使用一个Dll(动态链接库)来实现 这样,我们可以开发出Cygwin下的UNIX工具,使用这个DLL运行在W...
临时对象的构造/析构
产生临时对象的三种情况
系统架构设计(以飞控系统、航电系统、机电管理系统、电子电气架构为例)
系统架构涉及对系统的结构和行为进行高层次的描述。它包括系统的组成部分、这些部分之间的关系、与外部环境的交互方式,以及满足特定功能和非功能性需求的方法。系统架构定义了系统的总体设计蓝图,指导系统的开发、集成、部署和维护。系统架构设计的目的是通过合理的结构和设计原则,确保系统能够高效、稳定、安全地运行,满足当前和未来的需求,同时具备良好的维护性、扩展性和可持续性。良好的系统架构不仅能够提高系统的开发效率和运行性能,还能降低长期的维护和运营成本,支持系统的持续演进和技术更新。
扰动观察法MPPT控制器simulink仿真
最大功率点跟踪(MPPT)控制器对于光伏(PV)系统至关重要,因为它可以确保系统在所有操作条件下都能从光伏阵列中提取最大功率。扰动观察法(P&O)是一种广泛使用的MPPT算法,因为它简单且易于实现。本文介绍了P&O MPPT控制器的Simulink仿真,并分析了其性能。
c++ 类
C ++ 类 @(C/C++)[c++, 类] C ++ 类 1 类的定义/构造 1.1 关于类的理解 1.2 类的定义 2 类成员的可访问范围 3 内联成员函数/重载 3 构造函数 4 复制构造函数 4.1 复制构造函数的定义 4.2 复制构造函数的作用 5 类型转换构造函数 6 析构函数 6.1 析构函数的构造 6.2 析构函数的意义 6.3 析构函数的特点 6.4 析构函数...
C# USB通信实现
在C#中,我们可以利用.NET框架提供的类库和API来实现与USB设备的通信。本文将介绍如何使用C#进行USB通信,并提供相应的代码示例。以上就是使用C#进行USB通信的基本过程。通过以上代码示例,你可以实现与USB设备的简单通信,具体的实现方式和细节根据你的实际需求进行调整和扩展。命名空间,该命名空间包含了与串口通信相关的类和方法。选择需要通信的USB设备,然后使用。步骤二:获取可用的USB设备列表。首先,在你的C#项目中引入。步骤三:打开USB端口。步骤六:关闭USB端口。步骤一:引入命名空间。
【从浅学到熟知Linux】信号机制上篇=>信号的概念与产生方式(含signal/raise/abort函数使用示例、core dump核心转储、软件与硬件异常信号详解)
🏠关于专栏:Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。🎯每天努力一点点,技术变化看得见。
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
ET2012新版免狗免安装绿色软件
ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,
Python生成器及send用法讲解
- 生成器 我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数结束(可以看作隐式的返回None)。一旦函数将控制权交还给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据都将丢失。再次调用这个函数时,一切都将从头创建。 对于在计算机编程中所讨论的函数,这是很标准的流程。这样的函数只能返回一个值,不过,有时可以创建能...
锂电池充电器电路设计 里面有电路
锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。
【C++】指针和引用的差别
1. 非空区别, 在任何情况下
SAP B1中文培訓教材_SDK
公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说
【C++类和对象】一次讲透:构造函数、析构、拷贝控制与运算符重载
public:// —— 成员函数(也叫"方法")——void Init(int n = 4) // 定义在类内的成员函数,默认是 inlineperror("malloc申请空间失败");return;_top = 0;void Push(int x) // 入栈(简化版,未扩容)int Top()private:// —— 成员变量(也叫"属性/成员变量")——// ★ 分号千万不能省略!// 用类实例化出一个对象。
《dm_control+六轴机械臂》21 · 轨迹规划与抓取放置 ★
这一章要解决什么问题:第 20 章有了环境,但"怎么动"还没解决。 直接把目标位置发给机械臂会怎样?为什么要梯形速度剖面? 为什么夹爪开合要平滑?为什么抓取要用 weld? 这一章是全书最实战的一章——从「为什么」到「完整的抓取放置」,全流程实测。
C++中指针和引用的区别
从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。 而引用是一个别名(地址、类型),它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。 在C++中,指针和引用经常用于函数的参数传递,然而
python中的生成器send的作用_Python生成器及send用法讲解
- 生成器我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数结束(可以看作隐式的返回None)。一旦函数将控制权交还给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据都将丢失。再次调用这个函数时,一切都将从头创建。对于在计算机编程中所讨论的函数,这是很标准的流程。这样的函数只能返回一个值,不过,有时可以创建能产生一个序...
面试题目汇总,(不定时更新)
1.C++特性 抽象、封装、继承、多态 2.多态怎么实现的 多态:分为静态多态和动态多态: 静态多态:编译器在编译期间完成的,编译器会根据实参类型来推断该调用哪个函数,如果有对应的函数,就调用,没有则在编译时报错。 动态多态:其实要实现动态多态,需要几个条件——即动态绑定条件: 1、虚函数。基类中必须有虚函数,在派生类中必须重写虚函数。 2、通过基类类型的指针或引用来调用虚...
C++核心编程
变量类型存储区域生命周期地址特征全局变量全局区程序启动→结束地址小,固定静态变量全局区程序启动→结束地址小,固定局部变量栈区函数开始→结束地址大,每次运行可能不同局部常量栈区函数开始→结束地址大,和局部变量相邻全局常量常量区程序启动→结束地址中,只读字符串常量常量区程序启动→结束地址中,只读1.2 程序运行后 **栈区:** 由编译器自动分配释放, 存放函数的参数值,局部变量等 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。
JVM 虚拟机栈 栈帧
介绍JVM的虚拟机栈和栈帧
JavaScript相关面试题:1.js数据类型;2.JavaScript 语句的基本规范;3.事件代理;4.全局变量;5.哪些操作会造成内存泄漏;6.bind, call,apply
事件代理( Event Delegation), 又称为事件委托,是JavaScript 中绑定事件的常用技巧。顾名思义,“事件代理”就是把原本需要绑定的事件委托给父元素,让父元素负责事件监听。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。:全局变量是整个代码中都可用的变量,也就是说,这些变量没有任何作用域。var关键字用于声明局部变量,如果省略var关键字,则声明一个全局变量。使用全局变量面临的问题是局部变量和全局变量名称的冲突。......
753



被折叠的 条评论
为什么被折叠?



