Inheritance and its forms — Unit 3 Notes (Object Oriented Programming with C++)

BCS201 · Unit 3

Inheritance and its forms notes — Unit 3

Free unit-wise study notes on inheritance and its forms for Object Oriented Programming with C++, Semester 2 of B.Tech — Computer Science & Engineering — key concepts, examples, important questions and a revision checklist for semester exams.

An exhaustive deep-dive into Inheritance, the cornerstone of Code Reusability. This covers the memory models of inheritance, access specifier matrices, multipath inheritance, and solving the infamous Diamond Problem.

Notebook — 14 pages

Page 1

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

1. The Concept of Inheritance

Inheritance is the physical and logical process by which objects of one class (the derived class) acquire the properties and behaviors of another class (the base class). It is the implementation of the 'IS-A' relationship.

Why is Inheritance Critical?

  • Code Reusability: Once a base class is written and thoroughly debugged, it can be distributed. Other developers can inherit from it to create specific variants without rewriting the core logic.
  • Transitive Nature: If class A inherits B, and C inherits A, then C automatically contains the features of B. This creates logical family trees of software.
  • Polymorphic Base: Inheritance is the absolute prerequisite for Runtime Polymorphism (Virtual Functions). You cannot have polymorphism without an inheritance hierarchy.
Syntax of Inheritance
class Base { ... };

// Derived inherits Base using a visibility mode
class Derived : public Base { 
    // Additional properties and functions
};

Next — Page 2 — Terminology and Structure

1 of 14

Page 2

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

2. Terminology & Memory

Base vs Derived

Base Class (Super / Parent)

The generalized class whose properties are inherited. It has no knowledge of any classes that derive from it.

Derived Class (Sub / Child)

The specialized class that inherits from the Base. It contains BOTH the Base's non-private members AND its own new members.

Memory Layout of a Derived Object

When you create an object of a derived class, the system does not create a separate base object and derived object. It creates a SINGLE contiguous block of memory.

RAM for Derived Object `D`
---------------------------
[ Base Class Variables ] <- Inherited properties sit at the top
[ Derived Class Variables ] <- New properties sit underneath
Physical Memory Allocation

Because the base class variables exist physically inside the derived object's memory, a Base Pointer can safely point to a Derived Object without crashing.

Next — Page 3 — Single Inheritance

2 of 14

Page 3

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

3. Single Inheritance

Single inheritance is the simplest form, where a derived class inherits strictly from ONE and ONLY ONE base class.

[ Class A (Base) ]
[ Class B (Derived) ]
Single Inheritance Graph
Practical Example: Account System
class Account {
protected:
    double balance;
public:
    void deposit(double b) { balance += b; }
};

// SavingsAccount inherits EVERYTHING from Account
class SavingsAccount : public Account {
    double interestRate;
public:
    void addInterest() {
        balance += (balance * interestRate); // Accessing protected base member
    }
};

Here, `SavingsAccount` is heavily simplified because all the core ledger logic (deposit, balance tracking) is handled securely by `Account`.

Next — Page 4 — Multiple Inheritance

3 of 14

Page 4

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

4. Multiple Inheritance

C++ is one of the few languages (unlike Java or C#) that supports Multiple Inheritance: a derived class can inherit directly from MORE THAN ONE base class simultaneously.

[ Base1 ] [ Base2 ]
↘ ↙
[ Derived ]
Multiple Inheritance Graph
Syntax for Multiple Inheritance
class Printer {
public: void print() { cout << "Printing..."; }
};

class Scanner {
public: void scan() { cout << "Scanning..."; }
};

// Inherits from BOTH separated by commas
class MultiFunctionDevice : public Printer, public Scanner {
    // Has both print() and scan() automatically
};

Next — Page 5 — Multilevel & Hierarchical Inheritance

4 of 14

Page 5

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

5. Multilevel & Hierarchical

Multilevel Inheritance

A class inherits from a derived class, creating a multi-generational lineage. A -> B -> C.

class Animal { public: void eat(); };
class Mammal : public Animal { public: void breathe(); };
class Dog : public Mammal { public: void bark(); };
// Dog has eat(), breathe(), AND bark().

Hierarchical Inheritance

Multiple separate derived classes inherit from a SINGLE shared base class. This is extremely common in UI frameworks (e.g., UIElement -> Button, TextBlock, Image).

[ Shape ]
↙ ↓ ↘
[Circle] [Square] [Triangle]
Hierarchical Inheritance Graph

Hybrid Inheritance

A complex graph that mixes two or more of the above types. For example, A inherits B (Single), while C inherits D and E (Multiple), and F inherits A and C.

Next — Page 6 — Visibility Modes Matrix

5 of 14

Page 6

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

6. Visibility Modes Matrix

When writing `class Derived : [mode] Base`, the `mode` determines the maximum access level that inherited members will possess inside the Derived class.

How Access Modifiers Translate Downward
Base MemberPublic ModeProtected ModePrivate Mode
PrivateHiddenHiddenHidden
ProtectedProtectedProtectedPrivate
PublicPublicProtectedPrivate

Rule of Thumb: The Cap

Think of the visibility mode as a 'cap'.

  • If mode is `public`, it caps nothing. Public stays public.
  • If mode is `protected`, it caps public members down to protected. Now external code cannot access them, but future child classes can.
  • If mode is `private`, it caps everything down to private. The inheritance stops here. No further child classes will be able to access the base members.

Next — Page 7 — The Role of 'Protected'

6 of 14

Page 7

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

7. The 'Protected' Keyword

Before inheritance, a class only needs `public` and `private`. But inheritance creates a third demographic: child classes. This is why `protected` exists.

Public

Open to everyone. Main functions, other objects, child classes.

Protected

Closed to the outside world. Open ONLY to the class itself and its child classes.

Private

Closed to everyone except the class itself. Child classes are blocked.

Protected in Action
class Weapon {
protected:
    int damage; // Hidden from main(), but open to Sword
};

class Sword : public Weapon {
public:
    void sharpen() {
        damage += 10; // Valid! Child can access protected.
    }
};

int main() {
    Sword s;
    // s.damage = 100; // ERROR! Protected acts like private here.
}

Next — Page 8 — Constructor Execution Order

7 of 14

Page 8

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

8. Constructor Execution Order

When you create an object of a derived class, an intricate chain reaction of constructors fires off. The rule is strictly: Base to Derived.

The Top-Down Construction

Because the Derived class might rely on inherited variables in its own constructor, the Base class MUST be fully initialized first.

class A { public: A() { cout << "A "; } };
class B : public A { public: B() { cout << "B "; } };
class C : public B { public: C() { cout << "C "; } };

int main() {
    C obj; // Output will be: A B C
}

Destructor Execution Order

Destructors execute in the exact REVERSE order of constructors: Derived to Base. The derived class is torn down first, then the base class.

If `C` goes out of scope, the output of destructors will be: `~C ~B ~A`.

Next — Page 9 — Passing Args to Base Constructors

8 of 14

Page 9

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

9. Args to Base Constructors

If the Base class does not have a default constructor (meaning it REQUIRES parameters to be built), the Derived class MUST explicitly pass those parameters to the Base class when it is created.

Using the Initializer List

You pass parameters up the chain using the Initializer List syntax in the Derived class's constructor.

Passing arguments up the hierarchy
class Person {
    string name;
public:
    // Requires a string!
    Person(string n) : name(n) {}
};

class Employee : public Person {
    int id;
public:
    // Employee takes both, passes 'n' up to Person
    Employee(string n, int i) : Person(n), id(i) {
        // Person is fully constructed before this body runs
    }
};

Next — Page 10 — Ambiguity in Multiple Inheritance

9 of 14

Page 10

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

10. Ambiguity in Multiple Inheritance

Multiple inheritance brings a major architectural hazard: Name Collisions. If two parent classes have a function with the exact same name, the compiler throws an Ambiguity Error.

The Ambiguity Problem
class Machine {
public: void start() { cout << "Machine starting"; }
};

class Computer {
public: void start() { cout << "Booting OS"; }
};

class SmartDevice : public Machine, public Computer {};

int main() {
    SmartDevice device;
    // device.start(); // ERROR! Which start()?
}

Resolution using Scope

You must manually resolve the ambiguity by telling the compiler exactly which lineage to follow using the Scope Resolution Operator `::`.

    device.Machine::start();  // Prints: Machine starting
    device.Computer::start(); // Prints: Booting OS

Next — Page 11 — The Diamond Problem (Multipath)

10 of 14

Page 11

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

11. The Diamond Problem

The most infamous issue in C++ inheritance is Multipath Inheritance, globally known as The Diamond Problem.

The Setup

Consider a Grandparent class `Entity`. Two parent classes, `Character` and `Weapon`, both inherit from `Entity`. Now, a child class `MagicSword` inherits from BOTH `Character` and `Weapon`.

[ Entity (id) ]
↙ ↘
[ Character ] [ Weapon ]
↘ ↙
[ MagicSword ]
The Multipath Diamond

The Memory Crisis

Because `Character` inherited a copy of `Entity`, and `Weapon` inherited a copy of `Entity`, the bottom class `MagicSword` ends up inheriting TWO SEPARATE COPIES of `Entity` inside its memory block!

If you type `magicSword.id = 5;`, the compiler panics. Are you modifying the `id` belonging to the Character-half, or the Weapon-half? It's ambiguous and fundamentally wastes RAM.

Next — Page 12 — Virtual Base Classes

11 of 14

Page 12

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

12. Virtual Base Classes

C++ solves the Diamond Problem using Virtual Inheritance. By declaring the top-level base class as `virtual` when the middle classes inherit it, you instruct the compiler to only keep ONE shared instance of the Grandparent.

Solving the Diamond Problem
class Entity {
public: int id;
};

// 1. Inherit VIRTUALLY
class Character : virtual public Entity {};

// 2. Inherit VIRTUALLY
class Weapon : public virtual Entity {};

// 3. Bottom class inherits normally
class MagicSword : public Character, public Weapon {};

int main() {
    MagicSword ms;
    ms.id = 10; // NO ERROR! Only ONE shared 'id' exists.
}

How it works internally

Instead of copying the variables of `Entity` directly into `Character` and `Weapon`, the compiler inserts a hidden Virtual Base Pointer (vbptr) into them. When `MagicSword` is built, it uses those pointers to map both halves to a single, unified memory block for `Entity`.

Next — Page 13 — Object Slicing

12 of 14

Page 13

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

13. Object Slicing

A critical phenomenon occurs when you assign a Derived object directly into a Base object by value. This is known as Object Slicing.

The Slicing Mechanism

A Derived object is physically larger than a Base object because it contains extra variables. If you copy a Derived object into a Base object, there is no physical room for the extra variables. The compiler 'slices off' all the derived-specific data, leaving only the base portion.

class Base { public: int b; };
class Derived : public Base { public: int d; };

int main() {
    Derived objD;
    objD.b = 1; objD.d = 2;
    
    Base objB = objD; // Object Slicing occurs!
    // objB only has 'b'. 'd' is sliced off and lost forever.
}

Next — Page 14 — Unit 3 Revision Checklist

13 of 14

Page 14

Wink Notes

B.Tech CSE — 2nd Semester

Object Oriented Programming with C++

Unit - 3

14. Unit 3 Revision Checklist

End-of-Unit Verification

  • Write code to implement all 5 forms of inheritance.
  • Draw the physical memory layout of a derived class object.
  • Memorize the Visibility Matrix: What happens to a `protected` member when inherited `publicly` vs `privately`?
  • Explain exactly why `private` members of a base class are never accessible to derived classes.
  • Trace the execution order of Constructors and Destructors in a 3-level deep hierarchy.
  • Write the syntax to pass arguments to a parameterized base class constructor from a derived class.
  • Identify the ambiguity error in multiple inheritance and resolve it using `::`.
  • Draw the Diamond Problem architecture.
  • Explain how the `virtual` keyword alters memory allocation to fix Multipath Inheritance.
  • Explain Object Slicing and how to prevent it using pointers.

14 of 14

Continue in this subject