• 《C++反汇编与逆向分析技术揭秘》之十——析构函数


    • 局部对象

    当对象所在作用域结束之后,销毁栈空间,此时析构函数被调用。

    举例:

    函数返回时自动调用析构函数:

    • 堆对象

    调用析构代理函数来处理析构函数:

    为什么使用析构代理函数来调用析构函数?考虑到如果delete的对象是一个对象数组,可以使用析构代理函数依次析构所有的对象。举例:

    调用了构造代理函数:

     

    vector deleting destructor函数中先对标志位进行判断:

    如果没有跳转,表明delete的是一个数组,则会调用调用析构代理函数对对象进行逐一的析构。如果进行了跳转,则只进行一次析构函数的调用。

    •  参数对象和返回值

    参数对象会在函数调用结束时触发析构函数。

    返回值对象需要考虑两种情况:

    1、CMyString MyString = GetMyString()

    初始化一个对象时,会把这个对象的首地址传入GetMyString作为隐含参数,在函数内部完成拷贝构造函数。函数执行完毕时,MyString就已经构造完毕了,所以返回值对象的析构函数何时调用由它的作用域决定。

    2、MyString = GetMyString()

    举例:

    随后,并非以MyString的地址作为隐含参数传递给GetMyString,而是以一个局部的变量的地址作为隐含的参数传递给GetMyString():

    GetMyString内部会逐一拷贝函数内局部变量的内容给传递进去的地址(当然了,这是在没有显式定义复制构造函数的时候):

    如果显式定义了复制构造函数就会调用复制构造函数将局部对象的内容拷贝给传入的临时对象:

    GetMyString函数返回之后,逐一将临时对象的成员复制给MyString:

    最后,函数结束时会调用两次析构函数,分别析构临时对象和MyString:

    •  全局对象与静态对象

    它们的析构函数是在main函数执行之后调用。由exit内的doexit函数执行。

    举例:

    exit函数在main函数结束之后:

  • 相关阅读:
    中台入门系列1
    微服务 2.0 技术栈选型手册
    mysql计划任务每天定时执行
    更高效地提高redis client多线程操作的并发吞吐设计
    azure之MSSQL服务性能测试
    .NET Socket服务编程之-高效连接接入编
    轻易实现基于linux或win运行的聊天服务端程序
    零配置Socket TCP消息通讯服务容器EC
    azure存储压测的问题(农码主观意识太强被坑了)
    业务逻辑层缓存应该设计
  • 原文地址:https://www.cnblogs.com/predator-wang/p/8051547.html
Copyright © 2020-2023  润新知