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

 更新时间:2013年05月13日 09:09:38   作者:  
本篇文章对c++中临时对象的析构时机进行了详细的分析介绍,需要的朋友参考下

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语言main函数的参数及其返回值详细解析

    C语言main函数的参数及其返回值详细解析

    main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出;返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出
    2013-10-10
  • C语言结构体,枚举,联合体详解

    C语言结构体,枚举,联合体详解

    下面小编就为大家带来一篇全面了解C语言结构体,枚举,联合体。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09
  • C语言实现爆炸展开的扫雷详解

    C语言实现爆炸展开的扫雷详解

    windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本文将利用C语言实现这一经典的游戏,文中的示例代码讲解详细,感兴趣的可以学习一下,这篇文章主要介绍了C语言实现爆炸展开的扫雷游戏
    2022-07-07
  • c++野指针的原理以及避免方法

    c++野指针的原理以及避免方法

    这篇文章主要介绍了c++野指针的原理以及避免方法,帮助大家更好的学习和理解c++,感兴趣的朋友可以了解下
    2020-08-08
  • 深入讲解C++中的构造函数

    深入讲解C++中的构造函数

    这篇文章主要介绍了C++中的构造函数,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • 详解C++虚函数中多态性的实现原理

    详解C++虚函数中多态性的实现原理

    C++是一种面向对象的编程语言,在C++中,虚函数是实现多态性的关键。本文就来探讨一下C++虚函数中多态性的实现原理及其在面向对象编程中的应用吧
    2023-05-05
  • C++用winapi socket实现局域网语音通话功能

    C++用winapi socket实现局域网语音通话功能

    这篇文章主要介绍了socket实现局域网语音通话 c++ winapi,功能介绍支持录音设备查找以及播放设备查找,支持局域网语音通话,通话包含语音来电提醒和挂断电话的提示信息,还能实时的获取在线用户的数量以及对应的id,需要的的朋友一起看看
    2022-06-06
  • C语言驱动开发内核枚举IoTimer定时器解析

    C语言驱动开发内核枚举IoTimer定时器解析

    这篇文章主要为大家介绍了C语言驱动开发内核枚举IoTimer定时器解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • C语言如何计算两个数的最小公倍数

    C语言如何计算两个数的最小公倍数

    这篇文章主要介绍了C语言如何计算两个数的最小公倍数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C/C++高精度算法的实现

    C/C++高精度算法的实现

    这篇文章主要介绍了C/C++高精度算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论