C++对象内存布局,this指针,对象作为参数,作为返回值
class TestClass
{
public:
void setNum(int num)
{
m_num1 = num;
}
int getNum()
{
return m_num1;
}
private:
int m_num1;
int m_num2;
};
#include "pch.h"
#include <iostream>
#include "mytest.h" int main()
{
TestClass test;
test.setNum(); printf("sizeof testClass=%d,num = %d\n", sizeof(test), test.getNum()); std::cout << "Hello World!\n";
}
输出:sizeof testClass=8,num = 100
没有虚函数时,test变量在内存中的分布

若存在虚函数
class TestClass
{
public:
virtual void setNum(int num)
{
m_num1 = num;
}
virtual int getNum()
{
return m_num1;
}
private:
int m_num1;
int m_num2;
};


我们用IDA打开看一下反汇编
ext:004127B0 var_D8 = byte ptr -0D8h
.text:004127B0 var_14 = byte ptr -14h
.text:004127B0 var_4 = dword ptr -
.text:004127B0
.text:004127B0 push ebp
.text:004127B1 mov ebp, esp
.text:004127B3 sub esp, 0D8h
.text:004127B9 push ebx
.text:004127BA push esi
.text:004127BB push edi
.text:004127BC lea edi, [ebp+var_D8]
.text:004127C2 mov ecx, 36h
.text:004127C7 mov eax, 0CCCCCCCCh
.text:004127CC rep stosd
.text:004127CE mov eax, ___security_cookie
.text:004127D3 xor eax, ebp
.text:004127D5 mov [ebp+var_4], eax
.text:004127D8 mov ecx, offset unk_41E009
.text:004127DD call sub_411299
.text:004127E2 lea ecx, [ebp+var_14] // ecx 保存this指针,通过this指针地址偏移来调用类成员
.text:004127E5 call sub_411311
.text:004127EA push
.text:004127EC lea ecx, [ebp+var_14]
.text:004127EF call sub_41113B
.text:004127F4 lea ecx, [ebp+var_14]
.text:004127F7 call sub_4112A8
.text:004127FC push eax
.text:004127FD push 0Ch
.text:004127FF push offset aSizeofTestclas ; "sizeof testClass=%d,num = %d\n"
.text: call sub_411055
.text: add esp, 0Ch
.text:0041280C push offset Str ; "Hello World!\n"
.text: mov eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text: push eax ; int
.text: call sub_411226
对象作为返回值
1、分配一个临时对象空间 main_object;
2、把临时对象入栈
3、调用返回局部对象的函数
在返回局部对象的函数里面
fun_object;
一些局部变量操作
返回的时候用用局部对象作为参数,传入main_object对象的this指针
调用复制构造函数
用EAX返回this指针
tt=main_object;
一下转自:https://blog.csdn.net/qq_22660775/article/details/89854545
C++规定当函数返回的是非引用类型时,函数会创建临时对象(temporary object),函数返回的就是这个临时对象。在求解表达式时,如果需要一个地方存储其运算结果,编译器会创建一个没有命名的对象,这就是临时对象。浅显的说,当你调用了函数,函数会 return一个值 那么这个值总得有存放的地方吧,编译器就把会把值存放在一个没有命名法临时对象中。
我们举个例子来说明一下,首先定义一个类:
class B {
public:
B(){
cout << "B的构造函数" << endl;
}
B(int i){
cout << "带int型参数的B的构造函数" << endl;
}
B(const B &ano){
cout << "B的复制构造函数" << endl;
}
B& operator=(const B& rhs){
cout << "B的赋值操作符" << endl;
return *this;
}
virtual ~B(){
cout << "B的析构函数" << endl;
}
};
定义一个函数:
B func2()
{
B b;
return b;
}
上面的函数返回一个非引用类型的变量,我们写两个测试函数,来看看返回一个非引用类型的变量会发生什么
void test1() {
B t;
t = func2();
}
void test2() {
B t = func2();
}
运行测试函数test1(),其运行结果为:
B的构造函数 //构造主方法内的对象t
B的构造函数 //构造fun2内的局部对象b
B的复制构造函数 //将func2的局部对象复制到一个临时对象
B的析构函数 //析构局部对象b
B的赋值操作符 //使用临时对象初始化t
B的析构函数 //析构临时对象
B的析构函数 //析构对象t
由于 t 的初始化采用的是operator=操作符,operator=要求必须使用一个已经创建好了的对象对左值进行复制,所以此时必须先形成一个临时对象,然后将临时对象赋值给 t
运行测试函数test2(),其运行结果为:
B的构造函数 //构造fun2内的局部对象b
B的复制构造函数
B的析构函数
B的析构函数
由于 t 是通过复制构造函数进行初始化的。复制构造函数初始化要求左值是一个已有对象,而非创建好了的对象,因此此时不需要创建一个临时对象
C++对象内存布局,this指针,对象作为参数,作为返回值的更多相关文章
- c++ 指针做为参数和返回值
指针参数 返回值是指针 一.指针作参数形式的函数 //计算x的平方 x*x void square(int *x) { int a=*x; *x=a*a; } 二.指针作返回值的函数 int *squ ...
- Java对象内存布局
本文转载自Java对象内存布局 导语 首先直接抛出问题 Unsafe.getInt(obj, fieldOffset)中的fieldOffset是什么, 类似还有compareAndSwapX(obj ...
- JVM-对象及对象内存布局
目录 前言 类与对象 对象类二分模型 对象 对象内存布局 JOL工具 对象头 Mark Word 类型句柄 对象头与锁膨胀 无锁 偏向锁 轻量级锁 重量级锁 重量级锁降级 实例数据 填充 对象生命周期 ...
- 图说C++对象模型:对象内存布局详解
0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...
- c++ 对象内存布局详解
今天看了的,感觉需要了解对象内存的问题.参考:http://blog.jobbole.com/101583/ 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个 ...
- c++对象内存布局
这篇文章我要简单地讲解下c++对象的内存布局,虽然已经有很多很好的文章,不过通过实现发现有些地方不同的编译器还是会有差别的,希望和大家交流. 在没有用到虚函数的时候,C++的对象内存布局和c语言的st ...
- 从C++对象内存布局和构造过程来具体分析C++中的封装、继承、多态
一.封装模型的内存布局 常见类对象的成员可能包含以下元素: 内建类型.指针.引用.组合对象.虚函数. 另一个角度的分类: 数据成员:静态.非静态 成员函数:静态.非静态.虚函数 1.仅包含内建类型的场 ...
- c++对象内存布局的理解
我对c++对象内存布局的理解 引言 结合网上的一些资料,通过自己的一番摸索,得出了一点个人见解.现在写下来,希望与各位同学共同探讨,共同进步. 以下所有代码均是在VS2012下测试. 一个普通的基 ...
- 好文章系列C/C++——图说C++对象模型:对象内存布局详解
注:收藏好文章,得出自己的笔记,以查漏补缺! ------>原文链接:http://blog.jobbole.com/101583/ 前言 本文可加深对C++对象的内存布局.虚表指针.虚 ...
- 使用sos查看.NET对象内存布局
前面我们图解了.NET里各种对象的内存布局,我们再来从调试器和clr源码的角度来看一下对象的内存布局.我写了一个测试程序来加深对.net对象内存布局的了解: using System; using S ...
随机推荐
- S02_CH12_ AXI_Lite 总线详解
S02_CH12_ AXI_Lite 总线详解 12.1前言 ZYNQ拥有ARM+FPGA这个神奇的架构,那么ARM和FPGA究竟是如何进行通信的呢?本章通过剖析AXI总线源码,来一探其中的秘密. 1 ...
- vim 自定义设置
修改系统配置(面对所有用户): root@bogon:~# cd /etc/vim/ root@bogon:/etc/vim# ls vimrc vimrc.tiny root@bogon:/etc/ ...
- cocos creator图片渲染问题!
问题:游戏项目需要添加一个开场剧情(); 第一时间使用了cc.component.scheduleOnce (), 里面的回调函数为 cc.loader.loadRes(). 进入游戏时,渲染主场景后 ...
- 1.将控制器添加到 ASP.NET Core MVC 应用
模型-视图-控制器 (MVC) 体系结构模式将应用分成 3 个主要组件:模型 (M).视图 (V) 和控制器 (C). 模型(M):表示应用数据的类. 模型类使用验证逻辑来对该数据强制实施业务规则. ...
- K-匿名算法研究
12月的最后几天,研究了下k匿名算法,在这里总结下. 提出背景 Internet 技术.大容量存储技术的迅猛发 展以及数据共享范围的逐步扩大,数据的自动采集 和发布越来越频繁,信息共享较以前来得更为容 ...
- Cascader 级联选择器hover选择效果
官网例子 <div class="block"> <span class="demonstration">hover 触发子菜单< ...
- centos8安装chromium浏览器
1/yum install epel* [root@localhost framework]# yum list epl* Last metadata expiration check: 0:57:4 ...
- 软工个人项目———WC.exe(Java实现)
一.github地址 https://github.com/hhw-15521301615/hello-world 二.PSP表格 PSP2.1 Personal Software Process S ...
- Java开发环境之ActiveMQ
查看更多Java开发环境配置,请点击<Java开发环境配置大全> 柒章:ActiveMQ安装教程 1)去官网下载ActiveMQ安装包 http://activemq.apache.org ...
- Linux命令——jobs、bg、fg、nohup
参考:Bash基础——工作管理(Job control) jobs -l :除了列出 job number 与命令串之外,同时列出 PID 的号码: -r :仅列出正在背景 run 的工作:-s :仅 ...