为堆栈分配的对象调用析构函数的机制是什么?

时间:2009-09-01 12:54:07

标签: c++ stack destructor

C ++如何确保为堆栈分配的对象调用析构函数?当我按如下方式分配动态内存时,析构函数(或指向它的指针)会发生什么:

class MyClass {
public:

  ~MyClass()
  {
    std::cout<<"Destructor called."<<std::endl;
  }  

  MyClass()
  {
    std::cout<<"Constructor called."<<std::endl;
  }

};

....................................................................

//Limit scope for example
{
  MyClass instance;
}

构造函数和析构函数都被调用。这是怎么回事?

6 个答案:

答案 0 :(得分:7)

编译器在适当的位置插入对对象的析构函数的调用。

答案 1 :(得分:4)

你不会想知道为什么这个

{
  int i;
}

自动创建并销毁i,是吗? C ++做了很多工作,允许您创建行为类似于内置类型的类型。就像内置类型一样,在C ++中(除了在Java或C#之外),这个

{
  MyClass instance;
}

不只是定义可能绑定到null或某个实际对象的引用。它创建一个实际的对象。

对象创建分为两步:首先(在进入范围时)提供原始内存。然后(当遇到对象定义时)调用构造函数。对于内置类型,不会调用构造函数。如果不初始化内置变量,则它具有随机值。 (实际上它就是步骤#1中提供的内存中的位模式。)对象删除也有两个步骤:首先,调用析构函数(同样,不是内置函数),然后返回内存运行时系统。

(请注意,为堆栈变量提供和删除内存通常与导入/递减寄存器一样便宜。)

答案 2 :(得分:3)

创建变量后立即调用构造函数。对于析构函数,编译器在作用域的末尾发出代码来调用析构函数。要想到这一点,请尝试使用'goto'或switch / case结构过早退出作用域,并观察编译器是否抱怨。

答案 3 :(得分:3)

是的,调用构造函数和析构函数。更重要的是:

{
 MyClass instance;
 throw "exception";
}

在这个例子中,也调用了析构函数。这就是为什么我总是喜欢在堆栈上分配我的对象(或者至少用堆栈分配的监护人包装动态分配)。

答案 4 :(得分:1)

调用构造函数是因为您正在创建一个对象。调用析构函数是因为您清理了该对象。请记住,在C ++中,当堆栈范围消失时,堆栈上声明的对象会自动清除。

答案 5 :(得分:0)

嗯,它没有在构造函数之后调用析构函数 它在即将终止程序时调用它。

int main() {
    MyClass obj;
    cout<<"testing....1"<<endl;
    cout<<"testing....2"<<endl;
    return 0;
}

ans:

Constructor called.
testing....1
testing....2
Destructor called.