Compiler transforms to:
vtable for B: [0] offset_to_top = 0 [1] typeinfo pointer -> typeinfo for B [2] A::foo() thunk (if overriding) vtable for A: [0] offset_to_top = 0 [1] typeinfo pointer -> typeinfo for A c++ runtime
static Logger& getLogger() static Logger instance; // thread‑safe initialization return instance; Compiler transforms to: vtable for B: [0] offset_to_top
(simplified for a class hierarchy A <- B ): add x1, x1, :lo12:_ZNSt7__cxx1112
// Constructor function for global std::string _GLOBAL__sub_I_example.cpp: stp x29, x30, [sp, -32]! mov x0, :got:globalString bl _ZNSt7__cxx1112basic_string...C1E... // std::string::string(char const*) ldr x0, :got:__dso_handle adrp x1, :got:_ZNSt7__cxx1112basic_string...D1E... add x1, x1, :lo12:_ZNSt7__cxx1112...D1E... bl __cxa_atexit // register destructor for atexit ldp x29, x30, [sp], 32 ret // .init_array entry points to this function
When dynamic_cast<B*>(a_ptr) is performed, the runtime reads the vtable of the object to obtain the type_info of the most derived type and checks if it derives from B .