C++ Class Fundamentals: Virtual Functions, Polymorphism, and Class Relationships

class Parent { public: virtual void display() { cout << "Parent::display invoked" << endl; } };

class Child : public Parent { private: virtual void display() { cout << "Child::display invoked" << endl; } };

/* Parent declaration Child declaration Compilation result --------------- --------------- ----------------- public private Error private public or private OK public public OK

Polymorphic access depends on the access level in the base class. */

int main() { Child obj; Parent* ptr; ptr = &obj; ptr->display(); return 0; }


3 Relationship Between Derived and Base Classes ============ - Derived classes can add new member functions and variables, or redefine base class members - A derived class functions independently once defined—it contains all base class members and functions - Derived class members cannot access base class private members - A derived class object embeds a base class subobject; its size equals base class members plus newly added members, with the base portion stored at the beginning ### 3-1 Initialization Order of Base and Derived Classes - Base class constructors always execute before derived class constructors - After a derived class destructor completes, the base class destructor automatically runs ### 3-2 Name Hiding in Derived Classes When a derived class defines a member with the same name as a base class member, accessing that name defaults to the derived version. Qualify with the base class scope to access the base version. In practice, **redefining member variables with the same name is discouraged, though overloaded member functions are acceptable**. ### 3-3 Understanding the this Pointer For any object of class X, the this pointer references that object. Non-static member functions can use this implicitly to refer to the object on which the function operates. ### 3-4 Enclosing Classes and Their Characteristics Classes containing member objects are called **enclosing classes**. **Characteristics:** - Enclosing classes must ensure member objects initialize properly - Initialization occurs through the constructor's member initialization list - When an enclosing class constructs, member object constructors run first, followed by the enclosing class constructor - During destruction, the enclosing class destructor executes before member object destructors 4 Using const with Variables, Functions, and Objects ================== **Variables**: Declared values cannot change **Functions**: Parmaeters and local variables within the function remain immutable **Objects**: Can only invoke the destructor, constructor, and const member functions 5 Calculating Memory Footprint of C++ Classes ================= **Rules for C++ Class Size:** - Calculation considers **only member variables (with alignment rules)**, excluding static members and member functions - Classes or instances with virtual functions include the **vtable pointer size** (8 bytes on 64-bit systems) **Memory Alignment Rules**: Data addresses must align to 1, 2, 4, 8, or 16 byte boundaries. **Virtual Function Table Facts:** - Declaring virtual functions or inheriting from classes with virtual functions creates a vtable, represented by a pointer in each object - Overriding base virtual functions in a derived class replaces the corresponding entry in the vtable - Single inheritance with virtual functions yields one vtable; inheriting from N classes with virtual functions creates N vtables **Example** ```
#include <iostream>
using namespace std;

class EmptyClass {
};  // 1 byte - empty classes always occupy at least 1 byte

class WithVirtualChar {
    char data;
    virtual void method() { }
};  // 16 bytes: vtable pointer (8) + char padded to 8 bytes

class TwoChars {
    char first;
    char second;
    virtual void methodA() { }
    virtual void methodB() { }
};  // 16 bytes: vtable pointer (8) + two chars padded to 8 bytes

class MultiBase : public EmptyClass, public TwoChars {
    int value;
    virtual void methodA() { }
    virtual void methodB() { }
};  // 16 bytes: vtable pointer (8) + two chars + int, aligned to 16

class MultipleInheritance : public WithVirtualChar, public TwoChars {
    int number;
    virtual void method() { }
    virtual void methodB() { }
};  // 32 bytes: two vtable pointers (16) + three chars (8) + int (8)

int main() {
    cout << "EmptyClass: " << sizeof(EmptyClass) << endl;
    cout << "WithVirtualChar: " << sizeof(WithVirtualChar) << endl;
    cout << "TwoChars: " << sizeof(TwoChars) << endl;
    cout << "MultiBase: " << sizeof(MultiBase) << endl;
    cout << "MultipleInheritance: " << sizeof(MultipleInheritance) << endl;
    return 0;
}

Output: ``` EmptyClass = 1 WithVirtualChar = 16 TwoChars = 16 MultiBase = 16 MultipleInheritance = 32


References ==== 01 Standard C++ Programming, Guo Wei 02 MOOC: Programming and Algorithm Design (Part III)</div>

Tags: cpp virtual-functions Polymorphism Inheritance vtable

Posted on Thu, 14 May 2026 05:32:58 +0000 by amitsonikhandwa