【问题标题】:Confusion about destructor's calling关于析构函数调用的困惑
【发布时间】:2021-03-30 09:58:02
【问题描述】:

是在对象被销毁之前还是在对象被销毁之后调用析构函数? 我认为它是在对象被销毁之前调用的,因为在对象被销毁后我们无法访问该内存以释放其中的任何资源,但如果我错了,请纠正我,以便我能很好地理解它

#include <iostream>
#include <cassert>
#include <cstddef>
class Check
{
public:
    int neu{};
    Check() = default;
    Check(int n)
    {
        neu = n;
    }
    void print()
    {
        std::cout << neu << std::endl;
    }
    ~Check()
    {
        std::cout << "It has been destroyed "<<neu <<std::endl;
    }
};
int main()
{
    Check let,see(30);
    let.print();
    return 0;
    // does destructor gets called here
} // or does destructor gets called herecode here

【问题讨论】:

    标签: c++ class c++17 destructor


    【解决方案1】:

    是在对象被销毁之前还是在对象被销毁之后调用析构函数?

    在调用析构函数时,对象的生命周期已经结束。对象被析构函数销毁。

        // does destructor gets called here
    } // or does destructor gets called herecode here
    

    实际上并没有什么区别。

    自动对象在块内是活动的,在块外是不活动的。退出块时,对象将被销毁。因此,可以合理地说它们在右大括号所在的位置被销毁。

    【讨论】:

    • ...或从语言规则预定义的大括号中退出,包括例外情况
    • 或者调用delete。
    【解决方案2】:

    来自 ISO 标准(特殊成员函数 - 析构函数):

    一旦为一个对象调用析构函数,该对象就不再 存在;如果为某个对象调用析构函数,则行为未定义 生命周期已结束的对象。

    析构函数调用本质上是描述需要考虑对象被销毁的动作。可以显式调用析构函数,它会导致该对象的生命周期结束。显式调用很少见,通常用于放置 new 创建的对象。

    鉴于提供的示例,问题实际上是关于析构函数调用的顺序。之后调用子对象的析构函数(包括基类类型,如果有的话)。因此,您可以安全地访问它们,直到从析构函数中退出。调用顺序是基于声明顺序的,就像初始化的顺序一样,但是倒过来了。基类类型的子对象被认为是第一个初始化,最后一个销毁。

    【讨论】:

      猜你喜欢
      • 2011-11-21
      • 2013-02-01
      • 2015-07-13
      • 2018-04-26
      • 2015-04-08
      • 2013-12-31
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多