Question

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
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top