当我们使用“NEW”关键字创建对象时,为什么不调用析构函数?

时间:2014-05-22 11:04:57

标签: c++

我创建了一个带有一个构造函数和析构函数的类。在main函数中,我创建了一个指针并使用" new"初始化到我的类。关键词。

#include <iostream> 
using namespace std; 

class RAVI 
{ 
    public: 
    RAVI() 
    { 
        cout<<"in constructor"<<endl; 
    } 
    ~RAVI() 
    { 
        cout<<"in Distructor"<<endl;
    } 
};

int main()
{ 
    RAVI *p; 
    try{ 
        p= new RAVI(); 
        cout<<"throughng object"<<endl; 
        throw 6;
    } 
    catch(...)
    { 
        cout<<"Caught exception"<<endl; 
    } 
    cout<<"end of try-catch block"<<endl; 
    return 0; 
} 

这给出了输出:

in constructor 
throughng object 
Caught exception 
end of try-catch block

通常析构函数应该在抛出异常之前调用。但在下面的案例中为什么不发生?

请澄清我的疑问?

2 个答案:

答案 0 :(得分:4)

  

通常析构函数应该在抛出异常之前调用

<强> WRONG 即可。该对象在堆中分配,并将驻留在内存中,直到程序终止。如果您使用堆栈在try块中创建对象,那么当该块结束时它将被销毁,但在<{em> throw之后言。

 try{ 
  RAVI p;
  cout<<"throughng object"<<endl; throw 6; } 
 catch(...) 
{ 
  cout<<"Caught exception"<<endl;
}

输出:

in constructor
throughng object
in Distructor
Caught exception
end of try-catch block

我猜你假设“通常析构函数应该在抛出异常之前调用”,因为知道如果抛出异常,堆栈将展开并销毁在该范围内创建的所有对象。但对于驻留在堆栈中的对象(包括指针,而不是指向的对象),情况确实如此,而不是在堆中。这是使用智能指针而不是原始指针的动机,因此当堆栈展开时,堆对象也将被销毁。

答案 1 :(得分:1)

离开范围的所有局部变量的析构函数将是 调用。在您的情况下,没有局部变量离开 范围,因此不会调用析构函数。如果RAVI* p;在 try块,它的析构函数将被调用。但是 指针的析构函数是一个无操作符,所以你无法判断它是否存在 是否被召唤。

当您使用new创建对象时,您会告诉它 要管理其生命周期的编译器。唯一的一次 当你告诉编译器时,它的析构函数将被调用 这样做,delete