Domanda

I've got 3 classes

class A
{
    A();
    virtual ~A();
}
class B : public A
{
    B();
    ~B();
}
class C
{
    void *obj;
    C() : obj(nullptr) {}
    ~C() { if (obj) delete obj; }
}

when I use class C as a container for any child of class A and try to delete C instance. A, B destructor is not inveked is it normal? What is the solutuon?

C* instance = new C();
instance.obj = new B();
//Magic
delete instance; // A and B destructor is not called
È stato utile?

Soluzione

Deleting a pointer to an incompatible type (including void) gives undefined behaviour.

What is the solution?

  • use the correct type: either the type you specified with new, or a base class if it has a virtual destructor; or
  • use std::shared_ptr<void>, initialised from std::shared_ptr<correct_type>: its deleter will do the right thing.

In this case, it looks like you can simply store A* rather than void*, since you say it should be "a container for any child of class A".

By the way, there's no need to check whether the pointer is null before deleting it.

Altri suggerimenti

You delete a void*, so delete doesn't know that it's a B* so the destructor can't be called. You have to use a class pointer if you want the destructor to be called on deletion.

For example, is all classes that may be C's obj extend A, then use an A*.

Yes, delete needs the specific type.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top