删除指向子类的指针是否调用基类析构函数?

Does delete on a pointer to a subclass call the base class destructor?(删除指向子类的指针是否调用基类析构函数?)

本文介绍了删除指向子类的指针是否调用基类析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 class A,它为它的一个字段使用堆内存分配.类 A 被实例化并作为指针字段存储在另一个类中(class B.

I have an class A which uses a heap memory allocation for one of its fields. Class A is instantiated and stored as a pointer field in another class (class B.

当我处理完 B 类的对象时,我调用 delete,我假设它调用了析构函数...但这是否也调用了类 A 的析构函数?

When I'm done with an object of class B, I call delete, which I assume calls the destructor... But does this call the destructor of class A as well?

从答案中,我认为(如果不正确,请编辑):

From the answers, I take that (please edit if incorrect):

  1. delete B 的实例调用 B::~B();
  2. 调用A::~A();
  3. A::~A 应该显式delete A对象的所有堆分配的成员变量;
  4. 最后,存储所述类 B 实例的内存块返回到堆 - 当 new 被使用时,它首先在堆上分配一块内存,然后调用构造函数来初始化它,现在之后已调用所有析构函数来终结对象,对象所在的块将返回到堆中.
  1. delete of an instance of B calls B::~B();
  2. which calls A::~A();
  3. A::~A should explicitly delete all heap-allocated member variables of the A object;
  4. Finally the memory block storing said instance of class B is returned to the heap - when new was used, it first allocated a block of memory on heap, then invoked constructors to initialize it, now after all destructors have been invoked to finalize the object the block where the object resided is returned to the heap.

推荐答案

A 的析构函数将在其生命周期结束时运行.如果您希望释放其内存并运行析构函数,则必须将其删除(如果它是在堆上分配的).如果它是在堆栈上分配的,这会自动发生(即当它超出范围时;请参阅 RAII).如果它是类的成员(不是指针,而是完整成员),那么当包含对象被销毁时就会发生这种情况.

The destructor of A will run when its lifetime is over. If you want its memory to be freed and the destructor run, you have to delete it if it was allocated on the heap. If it was allocated on the stack this happens automatically (i.e. when it goes out of scope; see RAII). If it is a member of a class (not a pointer, but a full member), then this will happen when the containing object is destroyed.

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

在上面的例子中,每次删除和删除[]都是需要的.并且不需要删除(或确实可以使用)我没有使用它的地方.

In the above example, every delete and delete[] is needed. And no delete is needed (or indeed able to be used) where I did not use it.

auto_ptrunique_ptrshared_ptr 等...非常适合使生命周期管理更容易:

auto_ptr, unique_ptr and shared_ptr etc... are great for making this lifetime management much easier:

class A
{
    shared_array<char> someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr<A> APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically

这篇关于删除指向子类的指针是否调用基类析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:删除指向子类的指针是否调用基类析构函数?

基础教程推荐