当前位置:  编程技术>c/c++/嵌入式

深入c++中临时对象的析构时机的详解

    来源: 互联网  发布时间:2014-10-13

    本文导语:  c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源;而具名对象则是与创建的顺序相反,依次调用析构函数。 c++源码: 代码如下:class X  {public:   int i;   int j;   ~X() {}   X() {}}; int main() {    X x1;    X(); ...

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++四种强制类型转换的总结
  • 用C++实现strcpy(),返回一个char*类型的深入分析
  • c++关键字mutable深入解析
  • 深入分析C++中两个大数相乘结果不正确的问题
  • 深入理解:Java是类型安全的语言,而C++是非类型安全的语言
  • 深入理解C++中常见的关键字含义
  • 深入分析C++中执行多个exe文件方法的批处理代码介绍
  • 从汇编看c++中变量类型的深入分析
  • C++ using namespace std 用法深入解析
  • 深入解析C++中的mutable关键字
  • C++实现strcmp字符串比较的深入探讨
  • C++中virtual继承的深入理解
  • 虚函数与纯虚函数(C++与Java虚函数的区别)的深入分析
  • C++ Vector用法深入剖析
  • 深入C++中API的问题详解
  • C++中const的实现机制深入分析
  • 深入C++中inline关键字的使用
  • C++输入输出操作符重载的深入分析
  • 深入JDBC sqlserver连接写法的详解
  • 深入mysql YEAR() MONTH() DAYOFMONTH()日期函数的详解
  • 深入SQLServer中ISNULL与NULLIF的使用详解
  • 深入mysql并发插入优化详解
  • 深入android Unable to resolve target 'android-XX'详解
  • 深入MYSQL字符数字转换的详解
  • 深入SQL Server中定长char(n)与变长varchar(n)的区别详解
  • 深入C#任务管理器中应用程序选项隐藏程序本身的方法详解
  • 深入Windows下的回车是回车换行(rn)还是换行回车(nr)的详解
  • 深入分析NTFS中文件被锁定导致Process.Start失败的详解
  • 深入C# 内存管理以及优化的方法详解
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Docker支持更深入的容器日志分析
  • 关于《深入浅出MFC》
  • Linux有没有什么好的高级的书,我要深入,
  • 深入理解linux内核
  • [100分]有没有关于binutils的深入的资料?或者深入底层的资料?
  • 深入理解PHP内核 TIPI
  • 想深入学习Java应该学习哪些东西
  • 哪位有《JSP深入编程》电子版?
  • 想要深入学习LINUX该学什么?
  • 100分求:哪儿有《深入理解linux内核》可供下哉!
  • 如何深入Linux的内核学习?
  • U-BOOT得掌握到什么程序,用不用深入去学
  • 想深入了解操作系统该怎么做
  • 前一阵子学习了shell脚本,如果想深入点了解linux可以看什么书呢
  • 问一个《深入理解计算机系统》中的问题
  • 深入多线程之:深入分析Interlocked
  • ##想买书深入学习linux下的编程,请指教
  • 深入oracle特定信息排序的分析
  • 深入分析C中不安全的sprintf与strcpy
  • 哪儿有下载《深入理解Linux内核》这本书?(中文)
  • 请问JFC是否有必要深入研究?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3