从汇编看c++中临时对象的析构时机
http://www.cnblogs.com/chaoguo1234/archive/2013/05/12/3074425.html
c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源;而具名对象则是与创建的顺序相反,依次调用析构函数。
c++源码:

class X {
public:
int i;
int j;
~X() {}
X() {}
};
int main() {
X x1;
X();
x1.i = 1;
X x2;
}

对应的汇编码:

_main PROC
; 11 : int main() {
push ebp
mov ebp, esp
sub esp, 24 ; 为x1 临时对象 x2预留24byte空间
; 12 : X x1;
lea ecx, DWORD PTR _x1$[ebp];获取x1对象的首地址,作为隐含参数传入构造函数
call ??0X@@QAE@XZ ; 为x1调用构造函数
; 13 : X();
lea ecx, DWORD PTR $T2559[ebp];获取临时对象首地址,作为隐含参数传入构造函数
call ??0X@@QAE@XZ ; 为临时对象调用构造函数
lea ecx, DWORD PTR $T2559[ebp];获取临时对象首地址,作为隐含参数传入析构函数
call ??1X@@QAE@XZ ; 为临时对象调用析构函数
; 14 : x1.i = 1;
mov DWORD PTR _x1$[ebp], 1;将1写给x1首地址处内存,即将1写入x1中的成员变量i中
; 15 : X x2;
lea ecx, DWORD PTR _x2$[ebp];获取x2的首地址,作为隐含参数传入构造函数
call ??0X@@QAE@XZ ; 为x2调用构造函数
; 16 :
; 17 :
; 18 : }
lea ecx, DWORD PTR _x2$[ebp];获取x2的首地址,作为隐含参数传入析构函数
call ??1X@@QAE@XZ ; 为x2调用析构函数
lea ecx, DWORD PTR _x1$[ebp];获取x1的首地址,作为隐含参数传入析构函数
call ??1X@@QAE@XZ ; 为x1调用析构函数
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP

从上面的汇编码可以看出,临时对象确实是在不需要之后就调用了析构函数,尽管它在x2对象之前被创建,但依然在x2对象之前被析构。而x1 x2析构函数调用顺序,是与他们构造函数的调用顺序相反。
再看下面的情况:
c++中的源码:

class X {
public:
int i;
int j;
int k;
X() {}
~X() {}
};
int main() {
X x1;
X(), x1.i = 1;//这里有一条逗号运算符
X x2;
}

这里,改造临时对象之后,有一个逗号表达式,而不是分号。
下面是汇编码:

; 12 : int main() {
push ebp
mov ebp, esp
sub esp, 36 ; 为x1 临时对象 x2预留36字节的空间
; 13 : X x1;
lea ecx, DWORD PTR _x1$[ebp];获取x1的的首地址,作为隐含参数传递给构造函数
call ??0X@@QAE@XZ ; 为x1调用构造函数
; 14 : X(), x1.i = 1;//这里有一条逗号运算符
lea ecx, DWORD PTR $T2560[ebp];获取临时对象的首地址,作为隐含参数传递给构造函数
call ??0X@@QAE@XZ ; 为临时对象调用构造函数
mov DWORD PTR _x1$[ebp], 1;将1赋给x1首地址处的内存,即给x1的成员变量i赋值1
lea ecx, DWORD PTR $T2560[ebp];获取临时变量的首地址,作为隐含参数传递给析构函数
call ??1X@@QAE@XZ ; 为临时对象调用析构函数
; 15 : X x2;
lea ecx, DWORD PTR _x2$[ebp];获取x2的首地址,作为隐含参数传递给构造函数
call ??0X@@QAE@XZ ; 为x2调用构造函数
; 16 : }
lea ecx, DWORD PTR _x2$[ebp];获取x2的首地址,作为隐含参数传递给析构函数
call ??1X@@QAE@XZ ; 为x2调用析构函数
lea ecx, DWORD PTR _x1$[ebp];获取x1的首地址,作为隐含参数传递给析构函数
call ??1X@@QAE@XZ ; 为x1调用析构函数
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP

可以看到,与第一次不同的是,临时对象构造完毕之后,并没有立即调用析构函数,而是执行了逗号后面的赋值语句后,才调用的析构函数。
综上所述:
临时对象调用析构函数的时机是一条高级语言执行完毕的时候,而一条高级语言执行完毕的标志是分号。所以,临时对象调用析构函数的时机是碰到分号的时候
从汇编看c++中临时对象的析构时机的更多相关文章
- 从汇编看c++中全局对象和全局变量
先来看c++源码: #include <iostream> using namespace std; class X { public: int i; public: X() : i(ii ...
- 从汇编看c++中指向成员变量的指针(二)
在从汇编看c++中指向成员变量的指针(一)中讨论的情形没有虚拟继承,下面来看看,当加入了虚拟继承的时候,指向成员变量的指针有什么变化. 下面是c++源码: #include <iostream& ...
- [转] C++中临时对象及返回值优化
http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行 ...
- 转:C++中临时对象及返回值优化
http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行 ...
- 从汇编看c++中的多态
http://www.cnblogs.com/chaoguo1234/archive/2013/05/19/3079078.html 在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的 ...
- C++中临时对象的学习笔记
http://www.cppblog.com/besterChen/category/9573.html 所属分类: C/C++/STL/boost 在函数调用的时候,无论是参数为对象还是返回一个对 ...
- 从 php 源码看 php 中的对象
从一个简单的例子说起: class Person { public $name; public $age; public function __construct($name, $age) { $th ...
- 从汇编看c++中含有虚基类对象的析构
c++中,当继承结构中含有虚基类时,在构造对象时编译器会通过将一个标志位置1(表示调用虚基类构造函数),或者置0(表示不调用虚基类构造函数)来防止重复构造虚基类子对象.如下图菱形结构所示: 当构造类B ...
- 从汇编看c++中指向成员变量的指针(一)
在c++中,指向类成员变量的指针存储的并不是该成员变量所在内存的地址,而仅仅是该成员变量在该类对象中相对于对象首地址的偏移量.因此,它必须绑定到某一个对象或者对象指针上面,这里的对象和对象指针,就相当 ...
随机推荐
- 1.6 Hive配置metastore
一.配置 1.配置文件 #创建配置文件 [root@hadoop-senior ~]# cd /opt/modules/hive-0.13.1/conf/ [root@hadoop-senior co ...
- Linux下配置 禅道 (项目管理系统)
1.官网下载源码 2.解析一个新的子域名,然后到linux服务器上新建一个站点 3.将下载的文件上传至linux服务器(新建站点的时候已经在 /home/wwwroot/ 里建好了域名对应的文件夹,将 ...
- CSA Round #53 (Div. 2 only) Histogram Partition(模拟)
传送门 题意 给出一个数组A,你有一个数组B(一开始全为0),询问多少次操作后B转化为A 一次操作:选择一段区间,加上某个正整数 分析 构建一个栈, 输入一个数,若当前栈空或栈顶元素比输入小,则加入栈 ...
- CF888E Maximum Subsequence(meet in the middle)
给一个数列和m,在数列任选若干个数,使得他们的和对m取模后最大( \(1<=n<=35\) , \(1<=m<=10^{9}\)) 考虑把数列分成两份,两边分别暴力求出所有的可 ...
- java 三大基本特征
java中的面向对象的三大基本特征是:[封装].[继承].[多态] 封装:对象要有一个明确的边界:边界的划分(对象各司其职.对象的粒度.对象的可重用性) 属性(bean.pojo):私有的privat ...
- get 和 post 请求的区别(转)
转自 http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html http://www.nowamagic.net/librarys/ve ...
- cmd - 命令行窗口中文乱码
问题 在cmd窗口中输入curl www.baidu.com可以看到有中文乱码的现象,这是因为默认使用的是GBK编码.另外,curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在 ...
- gem install 提示rubygems.org连接不上的问题
周五的时候安装compass时遇到的,总是报错,后来反应过来是被墙了.解决办法就是使用淘宝的rubygem的镜像 gem sources --remove https://rubygems.org/ ...
- Centos 7.5源码编译安装zabbix4.0报fatal error: mysql.h: No such file or directory
系统环境:CentOS 7.5是最小化安装的 编译信息 编译选项: root@Server01 zabbix-]# ./configure --prefix=/usr/share/applicatio ...
- Spring Security – security none, filters none, access permitAll
1.概述 Spring Security提供了几种将请求模式配置为不安全或允许所有访问的机制.取决于这些机制中的哪一种 - 这可能意味着根本不在该路径上运行安全过滤器链,或者运行过滤器链并允许访问 2 ...