Inheritance and virtual functions add some complexity to memory alignment. Let's break this down by looking at different scenarios:
Here’s a code example that uses virtual functions:
#include <iostream>
// No virtual functions
struct Basic {
int Value;
char Tag;
};
// With virtual functions
struct Virtual {
virtual void Method() {}
int Value;
char Tag;
};
int main() {
std::cout << "Size without virtual: "
<< sizeof(Basic) << " bytes\n"
<< "Size with virtual: "
<< sizeof(Virtual) << " bytes\n"
<< "Alignment without virtual: "
<< alignof(Basic) << " bytes\n"
<< "Alignment with virtual: "
<< alignof(Virtual) << " bytes\n";
}
Size without virtual: 8 bytes
Size with virtual: 16 bytes
Alignment without virtual: 4 bytes
Alignment with virtual: 8 bytes
The size increase comes from the virtual function table pointer (vptr) added to objects with virtual functions. This pointer needs proper alignment too!
Here’s an example that shows some inheritance scenarios:
#include <iostream>
class Base {
int BaseValue;
char BaseTag;
};
class Derived : public Base {
double DerivedValue;
char DerivedTag;
};
class VirtualBase {
int BaseValue;
char BaseTag;
virtual void Method() {}
};
class VirtualDerived : public VirtualBase {
double DerivedValue;
char DerivedTag;
virtual void Method() override {}
};
int main() {
std::cout << "Regular inheritance:\n"
<< " Base size: " << sizeof(Base)
<< " bytes\n"
<< " Derived size: " << sizeof(Derived)
<< " bytes\n"
<< "\nVirtual inheritance:\n"
<< " Base size: " << sizeof(VirtualBase)
<< " bytes\n"
<< " Derived size: " << sizeof(VirtualDerived)
<< " bytes\n";
}
Regular inheritance:
Base size: 8 bytes
Derived size: 24 bytes
Virtual inheritance:
Base size: 16 bytes
Derived size: 32 bytes
Key points about inheritance and alignment:
Answers to questions are automatically generated and may not have been reviewed.
Learn how memory alignment affects data serialization and how to handle it safely