C ++:在没有显式析构函数的情况下删除指向类对象的指针会发生什么?

时间:2015-04-25 06:28:43

标签: c++

当您删除指向没有声明的析构函数的类的对象的指针时会发生什么?

4 个答案:

答案 0 :(得分:1)

每个类(或结构)都有一个析构函数(除非它是POD。如果你没有声明一个,编译器将添加一个隐式析构函数。以下面的类为例:

struct A
{
    std::string test;
};

没有为A定义析构函数。但它有一个,因为编译器会自动添加它。它甚至都不是空的。它会调用测试的析构函数,因为std :: string本身就有一个析构函数。

答案 1 :(得分:1)

根据C ++标准(12.4 Destructors)

  

4如果一个类没有用户声明的析构函数,那么析构函数就是   隐含地宣布为违约(8.4)。一个含蓄的声明   析构函数是其类的内联公共成员。

     

11 ...对于由new-expression(5.3.4)分配的构造对象,还通过使用 delete- expression (5.3.5)隐式调用析构函数;

所有析构函数都执行以下操作,只是隐式定义的析构函数具有空体,因此没有在其体内分配自动对象。

  

8执行析构函数体后破坏任何析构函数   在body中分配的自动对象,类X的析构函数   为X的直接非变量非静态数据调用析构函数   成员,X的直接基类的析构函数,如果X是   最派生类的类型(12.6.2),它的析构函数调用   X的虚拟基类的析构函数。所有的析构函数都被称为   好像它们是用限定名称引用的,即忽略   更多派生类中任何可能的虚拟覆盖析构函数。   基地和成员按完成的相反顺序销毁   他们的构造函数(见12.6.2)。 a中的返回声明(6.6.3)   析构函数可能不会直接返回调用者;之前   将控制权转移给呼叫者,成员的析构者   和基地被称为。调用数组元素的析构函数   按其构造的相反顺序(见12.6)。

答案 2 :(得分:0)

我假设通过删除指向类C的指针p表示

C *p;
<some init and work>
delete p;

如果C类没有显式声明析构函数,编译器将隐式添加析构函数。

这个隐式析构函数在销毁实例时被调用 班级无所事事。

n.b。隐式添加的析构函数是内联的公共。

答案 3 :(得分:0)

隐式声明的析构函数 如果没有为类类型(struct,class或union)提供用户定义的析构函数,编译器将始终将析构函数声明为其类的内联公共成员。

删除了隐式声明的析构函数 如果满足以下任何条件,则类T的隐式声明或默认析构函数未定义(直到C ++ 11)被定义为已删除(自C ++ 11起): T有一个不能被破坏的非静态数据成员(已删除或无法访问的析构函数) T具有无法破坏的直接或虚拟基类(已删除或无法访问的析构函数) T是一个联合体,并且具有带有非平凡析构函数的变体成员。 (自C ++ 11以来) 隐式声明的析构函数是虚拟的(因为基类具有虚拟析构函数),并且查找解除分配函数(operator delete()会导致调用不明确,已删除或无法访问的函数。

#include <iostream>

struct A
{
    int i;

    A ( int i ) : i ( i ) {}

    ~A()
    {
        std::cout << "~a" << i << std::endl;
    }
};

int main()
{
    A a1(1);
    A* p;

    { // nested scope
        A a2(2);
        p = new A(3);
    } // a2 out of scope

    delete p; // calls the destructor of a3

}

output:
~a2
~a3
~a1