C ++:析构函数如何在内部工作以及谁调用默认的析构函数?

时间:2014-02-20 14:45:45

标签: c++ destructor

class A
{
    public:
    A()
    {
       std::cout << "I am ctor\n";
    }
    ~A()
    {
       std::cout << "I am dtor\n";
    }
    void printme()
    {
       std::cout << "I am printme\n";
    }
};

int main()
{
   A aobj;
   aobj.printme();
   aobj.~A();
   aobj.printme();
   return 0;
}

这是输出:

$./testdtor
I am ctor
I am printme
I am dtor
I am printme
I am dtor

对析构函数的显式调用就像普通函数调用一样,一旦对象超出范围,就会调用析构函数,但我想知道哪个实体?

3 个答案:

答案 0 :(得分:6)

编译器为所有自动对象生成析构函数调用代码。这些析构函数的调用顺序与对象构造顺序相反。

delete运算符为驻留在operator参数指向的地址的对象调用对象析构函数,并且通常(我会说总是)与动态对象一起使用。

此行为允许可靠的内存管理以及我​​们在C++中非常喜欢的许多其他有用技巧。

您可能并且在大多数情况下手动调用析构函数的唯一情况是使用placement new运算符分配对象时。

答案 1 :(得分:6)

这取决于对象的位置以及它的生命周期。

  • 对于自动变量,例如您的示例,通过在其范围结束时生成的代码
  • 对于静态变量,在atexit结束后由main机制调用的代码
  • 对于线程局部变量,在线程结束后通过类似的机制
  • 对于非静态类成员变量或基础子对象,通过在包含它的类的析构函数中生成的代码
  • 对于由new创建的对象,由相应的delete-expression
  • 生成的代码
  • 对于placement-new创建的对象,只能显式调用析构函数。

答案 2 :(得分:0)

内部析构函数是一种常用函数。它用于释放类使用的资源,它可以有任何行为。

对析构函数的调用由编译器生成。它在以下时间调用:

1对象超出范围

void foo() {
    // Declare an instance of some object
    MyClass object;

    // code

    // destructor for 'object' called here
}

2删除对象时:删除myPtr

3删除对象数组时:delete [] myArray

4如果抛出异常,则为范围

中的所有对象调用析构函数

有一种情况是不会调用析构函数。如果在执行对象的构造函数中抛出异常并在不被捕获的情况下将其转义,则不会调用此对象的析构函数。

相关问题