C, C++, MFC  

Chapter 11: Inheritance: Building Class Hierarchies in C++

Previous chapter: Chapter 10: Classes and Objects: Construction and Destruction

Inheritance is one of the foundational pillars of Object-Oriented Programming (OOP) in C++. It allows a new class (Derived Class or Subclass) to inherit properties (data) and behavior (methods) from an existing class (Base Class or Superclass). This mechanism promotes code reuse and establishes a clear is-a relationship between classes (e.g., a Dog is a Mammal).

1. Base and Derived Classes

The derived class inherits all the members of the base class but can also add its own unique features or redefine inherited ones.

Syntax for Inheritance

class Animal { // Base Class
public:
    void eat() {
        std::cout << "The animal eats food." << std::endl;
    }
};

// Dog is derived from Animal (public inheritance)
class Dog : public Animal { // Derived Class
public:
    void bark() {
        std::cout << "The dog barks." << std::endl;
    }
};

int main() {
    Dog my_dog;
    my_dog.eat(); // Inherited from Animal
    my_dog.bark(); // Unique to Dog
    return 0;
}

2. Access Specifiers and Inheritance

The access specifier used during inheritance (public, private, or protected) affects how the inherited members can be accessed in the derived class and by the outside world.

Base Class MemberPublic InheritanceProtected InheritancePrivate Inheritance
publicRemains publicBecomes protectedBecomes private
protectedRemains protectedRemains protectedBecomes private
privateNot accessibleNot accessibleNot accessible

The protected modifier, introduced here, is accessible within the base class itself and by all its derived classes, but not by external code (unlike public). This is ideal for members needed by subclasses but hidden from the public.

3. Order of Construction and Destruction

When a derived class object is created, the constructor of the Base Class is called first, followed by the constructor of the Derived Class.

When the object is destroyed, the Derived Class destructor is called first, followed by the Base Class destructor.

This ensures that the base structure is fully initialized before the specific parts, and cleaned up in reverse order.

class Base {
public:
    Base() { std::cout << "1. Base Constructor" << std::endl; }
    ~Base() { std::cout << "3. Base Destructor" << std::endl; }
};

class Derived : public Base {
public:
    Derived() { std::cout << "2. Derived Constructor" << std::endl; }
    ~Derived() { std::cout << "4. Derived Destructor" << std::endl; }
};

// Output sequence: 1, 2, 4, 3

4. Overriding Base Class Methods

A derived class can redefine a member function inherited from the base class. This is called method overriding.

class Vehicle {
public:
    void start_engine() {
        std::cout << "Basic engine starting sequence." << std::endl;
    }
};

class Truck : public Vehicle {
public:
    // Overriding the base method
    void start_engine() {
        std::cout << "Heavy-duty engine starting sequence." << std::endl;
    }
};
// When calling Truck::start_engine(), the Truck version is executed.

This sets the stage for the powerful concept of polymorphism, which we explore next.