// From http://en.cppreference.com/w/cpp/language/virtual // // Build with: g++ -Wall -o inh inh.cc // Disassemble with: objdump -d inh OR gobjdump -d inh (On MacOS) #include struct Base { int a = 0, b = 0 , c = 0; // The above causes a 'C++11' warning. To avoid the warning, change to explicit initialization in the constructor: // int a, b, c; // Base() { a = 0; b = 0; c = 0; } // OR Base() : a(0), b(0), c(0) { } virtual void foo() { // <--- note "virtual"! This adds a VPTRs to each Base and Derived object instance, // and a VTABLE per each class. Find references to these in disassembly. std::cout << "base\n"; } }; // every object of type Derived includes Base as a subobject struct Derived : Base { int b = 1; // this will shadow the Base's b, depending on how it's accessed (see below) // Same deal about the warning: // int b; // Derived() { b = 1; } // OR Derived() : b(1) { } void foo() { // OR: void f() override { // 'override' is optional std::cout << "derived\n"; } }; int main() { Base b; Derived d; Base* bp = &b; // Derived* dp = &d; // Try this with Base* first, notice where the output differs---and doesn't! bp->foo(); // prints "base" dp->foo(); // prints "derived" // Calling a method of an object through the base class pointer. bp = (Base *) &d; bp->foo(); // <----- this is the heart of C++ inheritance-based OO! std::cout << "member b via ptr: " << bp->b << " " << dp->b << std::endl; return 0; }