【问题标题】:When are destructors called in c++? [duplicate]c++中什么时候调用析构函数? [复制]
【发布时间】:2016-07-15 05:40:07
【问题描述】:

我知道每当一个对象超出范围删除编译器会自动调用析构函数,但我怎么知道一个对象的范围呢?

例如在这段代码中:

    #include<iostream>
using namespace std;

class demo
{
    static int count;
public:
    demo()
    {
        cout<<"object created"<<++count<<endl;
    }
    ~demo()
    {
        cout<<"object destroyed"<<count--<<endl;
    }
};
int demo::count;
int main()
{
    cout<<"in main\n";
    demo d1;
    {
        cout<<"in block 1\n";
        demo d2;
        {
            cout<<"in block 2\n";
            demo d3;
        }
    }
    {
        cout<<"in block 3\n";
        demo d4;
    }
    cout<<"exit\n";
}

每个对象的作用域是什么?

【问题讨论】:

  • 您是否尝试过实际编译和运行这段代码?
  • 按顺序执行:构造函数被调用:demo d1 -> demo d2 -> demo d3 -> demo d4。析构函数被调用:-> demo d3 -> demo d2 -> demo d4 -> demo d1。发生这种情况的原因是,每个 { } 在堆栈帧上都有自己的一组开始和结束地址。每次遇到新对象时,都会在必要的范围({})下创建它。当您离开该范围时,它会被析构函数调用(除非它被分配或配置为静态变量。)所以每个的输出:
  • Constructors && Destructors Combined-> 对象已创建 1 个对象已创建 2 个对象已创建 3 个对象已销毁 3 个对象已销毁 2 个对象已创建 2(表示对象 4)已销毁对象 2(表示对象 4)已销毁对象 1 个只是看代码,可能这里或那里有问题。

标签: c++


【解决方案1】:

对象的范围是当它离开声明它的{ } 时。这是针对局部变量,而不是针对静态和全局变量。

在您的 ecample 中,对象将按以下顺序离开范围:d3d2d4d1。请注意d1d4在同一个作用域内,同一作用域内对象的删除规则与分配顺序相反。

【讨论】:

    【解决方案2】:

    C++ 中的对象既可以在栈上创建,也可以在堆上创建。

    堆栈帧(或范围)由语句定义。这可以像函数一样大,也可以像流控制块一样小(while/if/for 等)。包含任意代码块的任意 {} 对也构成堆栈帧。一旦程序退出该框架,在框架内定义的任何局部变量都将超出范围。当堆栈变量超出范围时,将调用其析构函数。

    当它在堆中创建时,应该通过在对象上调用“delete”来销毁它

    取自post

    【讨论】:

      猜你喜欢
      • 2019-11-15
      • 1970-01-01
      • 2019-04-07
      • 2015-09-23
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 2021-02-16
      • 1970-01-01
      相关资源
      最近更新 更多