#include <iostream>
#include <cstdint>
void* get_vptr(void* obj) {
return *reinterpret_cast<void**>(obj);
}
class Base {
public:
Base() {
std::cout << "Base constructor: vtable pointer = " << get_vptr(this)
<< " -> calling virtual function: ";
f();
}
virtual ~Base() {
std::cout << "Base destructor: vtable pointer = " << get_vptr(this)
<< " -> calling virtual function: ";
f();
}
virtual void f() {
std::cout << "Base::f()\n";
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Derived constructor: vtable pointer = " << get_vptr(this)
<< " -> calling virtual function: ";
f();
}
~Derived() override {
std::cout << "Derived destructor: vtable pointer = " << get_vptr(this)
<< " -> calling virtual function: ";
f();
}
void f() override {
std::cout << "Derived::f()\n";
}
};
int main() {
std::cout << "=== Creating Derived object ===\n";
Derived d;
std::cout << "\n=== Calling virtual function through Base pointer (after object is fully constructed) ===\n";
Base* ptr = &d;
ptr->f();
std::cout << "\n=== Manual destructor (automatic destructor when leaving scope) ===\n";
std::cout << "\n=== About to leave main, object will be automatically destructed ===\n";
return 0;
}