C++ Object Memory Model
Summary
// some examples:
struct a { void foo(); }; // no need for virtual table
struct b : a { virtual foo1(); }; // need vtable, and vptr
struct c : b { void bar(); }; // no extra virtual table, 1 vptr (b) suffices
struct d : b { virtual bar(); }; // 1 vtable, d extends b's vtable
struct e : d, b {}; // 2 vptr, 1 for the d and 1 for b
struct f : virtual b {}; // 1 vptr, f reuse b's vptr to locate subobj b
struct g : virtual b {}; // 1 vptr, g reuse b's vptr to locate subobj b
struct h : f, g {}; // 2 vptr, 1 for f, 1 for g
// h can locate subobject b using f's vptr
Basically each sub-object of a type that requires its own dynamic dispatch (cannot directly reuse the parents) would need its own virtual table and vptr.
Only class which has virtual method will have vptr
Class with inheritance
class Base {
public:
int baseVar;
};
class Derived : public Base {
public:
double derivedVar;
virtual void foo();
};
Memory Layout
Base Object
+---------------------+
| baseVar |
+---------------------+
Derived Object
+---------------------+
| vptr | // Pointing to Derived vTable
+---------------------+
| baseVar | // from Base
+---------------------+
| derivedVar | //from Derived
+---------------------+
Class with inheritance (Base is also virtual)
class Base {
public:
int baseVar;
virtual void foo();
};
class Derived : public Base {
public:
double derivedVar;
virtual void foo();
};
Memory Layout
Base Object
+---------------------+
| vptr | // Pointing to vTable for Base
+---------------------+
| baseVar |
+---------------------+
Derived Object
+---------------------+
| vptr | // Pointing to Derived vTable
+---------------------+
| baseVar | // from Base
+---------------------+
| derivedVar | //from Derived
+---------------------+
Class with multiple inheritance
class Base1 {
public:
int baseVar1;
virtual void foo();
};
class Base2 {
public:
int baseVar2;
virtual void foo();
};
class Derived : public Base, public Base2 {
public:
double derivedVar;
void foo() override;
};
Memory Layout
Base Object1
+---------------------+
| vptr | // Pointing to vTable for Base1
+---------------------+
| baseVar1 |
+---------------------+
Base Object2
+---------------------+
| vptr | // Pointing to vTable for Base2
+---------------------+
| baseVar2 |
+---------------------+
Derived Object
+---------------------+
| vptr | // Pointing to Derived vTable for Base1 (Base1 + Derived methods)
+---------------------+
| baseVar |
+---------------------+
| vptr | // Pointing to Derived vTable for Base2
+---------------------+
| baseVar2 |
+---------------------+
| derivedVar | //from Derived
+---------------------+
References
https://shaharmike.com/cpp/vtable-part1/
https://stackoverflow.com/questions/3342035/how-many-vptr-will-a-object-of-classuses-single-multiple-inheritance-have