Home > Software design >  How do I correctly destruct a derived object that was constructed using placement new
How do I correctly destruct a derived object that was constructed using placement new

Time:05-19

Say we have a C program with this sort of class inheritance:

class A {
public:
   virtual ~A() {/* ... */}
};

class B : public A {
public:
   virtual ~B() {/* ... */}
};

class C : public A {
public:
   virtual ~C() {/* ... */}
};

And furthermore, there are specialized memory constraints which requires that B and C must always be allocated in a special region of RAM (e.g. a reserved region of physical SRAM that guarantees faster response times than normal SDRAM) and so we must never allocate instances of B or C from the general heap. So we might have something like:

A * ptr;

if(condition) {
   ptr = specialized_allocator(sizeof(B));
   new(ptr) B;
} else {
   ptr = specialized_allocator(sizeof(C));
   new(ptr) C;
}

/* Do something, which persists beyond the scope
   of the function where allocation occurred... */

ptr->~A();
specialized_deallocator(ptr);

In this scenario, will the complete chain of derived class destructors be invoked correctly, or will it end up only invoking the top-level A destructor?

CodePudding user response:

Run this and it may help a little:

#include <iostream>

class A {
public:
    virtual ~A() { std::cout << "A\n"; }
};

class B : public A {
public:
    virtual ~B() { std::cout << "B\n"; }
};

class C : public A {
public:
    virtual ~C() { std::cout << "C\n"; }
};

int main()
{
    A* ptr = new C(); // or A* ptr = new B()
    // ...
    ptr->~A();
}
  • Related