从汇编看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++中,指向类成员变量的指针存储的并不是该成员变量所在内存的地址,而仅仅是该成员变量在该类对象中相对于对象首地址的偏移量.因此,它必须绑定到某一个对象或者对象指针上面,这里的对象和对象指针,就相当 ...
随机推荐
- Coding 两步认证技术介绍
什么是两步认证 在介绍两步认证之前,首先来看下目前主流的几种认证方式. 上图中的认证方式大体上可以分为三大类 1.You know : 比如密码,这种只有我们知道的 2.You are : 比如指纹, ...
- 用spin和edit控件来用spin控制edit里面小数的增减
1.响应SPIN的消息,就是点SPIN的上键头和下键头的消息,在这个消息里改变值是以0.1步进量增减.2.使用UpdateData(FALSE)来更新EDIT的关联的double型的变量. 创建步骤 ...
- HDU5950【矩阵快速幂】
主要还是i^4化成一个(i+1)^4没遇到过,还是很基础的一题矩阵快速幂: #include <bits/stdc++.h> using namespace std; typedef lo ...
- Cocos2d-x-html5之HelloWorld深入分析与调试
Cocos2d-x-html5之HelloWorld深入分析与调试 另:本章所用Cocos2d-x版本为: Cocos2d-html5-v2.1.1 http://cn.cocos2d-x.org/d ...
- Codevs 1141 数列
1141 数列 题目描述 Description 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9, ...
- 洛谷CF895C Square Subsets(线性基)
洛谷传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 题意: 给你n个数,每个数<=70,问有多少个集合,满足集合中所有数相乘是个完全平方数(空集除外) 题解: 完全看不出这玩意儿和线性基有什 ...
- 【UVA - 10815】Andy's First Dictionary (set)
Andy's First Dictionary Description 不提英文了 直接上中文大意吧 XY学长刚刚立下了再不过CET就直播xx的flag,为了不真的开启直播模式,XY学长决定好好学习英 ...
- Mysql用户root密码找回
1.本试例的环境如下: 2.mysql数据库的版本如下,此数据库运行多实例: mysql Ver 15.1 Distrib 10.2.24-MariaDB, for Linux (x86_64) us ...
- mysql驱动包下载
- cmd 查看端口占用情况
netstat -nao|findstr 端口号 打开任务管理器查看