What you do is UB, but for the particular compiler you use, the behavior can be described as follows. To simplify the ASCII graphics below by changing the example, adding a member yto Dand changing main.
#include <iostream>
using namespace std;
class B
{
public:
B() { cout << "Base B()" << endl; }
~B() { cout << "Base ~B()" << endl; }
private:
int x;
};
class D : public B
{
public:
D() { cout << "Derived D()" << endl; }
virtual ~D() { cout << "Derived ~D()" << endl; }
private:
int y;
};
int
main ( void )
{
D* d = new D;
B* b = d;
delete b;
}
In the compiler used, the virtual table, if any, is placed at the beginning of the memory block. In the compiler, you use the memory layout for this:
+--------+
| vtable | <--- d points here, at the start of the memory block.
+--------+
| x | <--- b points here, in the middle of the memory block.
+--------+
| y |
+--------+
delete b free b, .
, , - .