class Item
{
longlongint _id;
public:
Item(longlongint id) :
_id{id}
{
}
longlongint id() const
{
return _id;
}
// Required to get addresses of members
friendvoid print_offsets();
};
/*******************************************************************************
Memory layout:
+-ItemToBuy----------------+
| vptr : void* | 8 bytes
| _price : int | 4 bytes
| 8 BYTE ALIGNMENT PADDING | 4 bytes
+-Item---------------------+ Memory may not be continuous with a virtual base
| _id : long long int | 8 bytes
+--------------------------+
Total size is 24 bytes.
*******************************************************************************/
class ItemToBuy : virtualpublic Item
{
int _price;
public:
ItemToBuy(int price) : Item{123},
_price{price}
{
}
int price() const
{
return _price;
}
// Required to demonstrate dynamic_cast
virtual ~ItemToBuy()
{
}
// Required to get addresses of members
friendvoid print_offsets();
};
I'm not a compiler writer, but removing virtual from the subclass destructor doesn't seem to remove the vtable by itself, based on sizeof(ItemToBuy). But removing the virtual from the destructor and making it just be public inheritance instead of virtual public inheritance reduced the size to 16 instead of 24, which would suggest the vtable is removed.
Apparently preventing the diamond problem (the point of virtual inheritance) also requires a vtable. I assume it does this to allow the two different subclass objects to point to the same superclass. I guess that's why it's called virtual inheritance.