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
};
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.
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 GraphPractical 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`.
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 GraphSyntax 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
};
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.
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 Member
Public Mode
Protected Mode
Private Mode
Private
Hidden
Hidden
Hidden
Protected
Protected
Protected
Private
Public
Public
Protected
Private
⇒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.
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.
}
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`.
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
}
};
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
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.
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`.
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.
}
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.