Object Oriented Programming in C++Unit 58 min read
Inheritance in C++: Types, Code Reuse & Problem-Solving
Unit 5 of Object Oriented Programming in C++ covers inheritance (how classes inherit properties/methods), its five types (single, multilevel, hierarchical, multiple, hybrid), the diamond problem, and real-world applications in banking, e-commerce, and system design—with code examples, visual traces, and exam-focused ti
TAKEAWAYS:
- Inheritance lets a derived class reuse code from a base class via
:syntax, saving time and reducing errors. - Five types of inheritance (single, multilevel, hierarchical, multiple, hybrid) solve different design needs—each has pros/cons.
- The diamond problem (ambiguous base class) is fixed using virtual inheritance in C++.
- Real-world systems (e.g., Khalti’s payment hierarchy, Ncell’s billing structure) use inheritance to organize complex logic.
- Exam focus: Code traces, UML diagrams, and explaining why a design choice (e.g.,
virtualkeyword) matters.
1. What is Inheritance?
Inheritance is an OOP mechanism where a derived class (child) inherits properties and behaviors from a base class (parent). It promotes code reusability and logical hierarchy.
Key Terms
- Base Class: The class being inherited from (e.g.,
Person). - Derived Class: The class that inherits (e.g.,
Employee). public/protected/privateinheritance: Controls access to base class members.:syntax: Used to declare inheritance (e.g.,class Employee : public Person).
Why Use Inheritance?
- Avoid redundancy: Write once, reuse everywhere.
- Model real-world relationships: E.g., an
Employeeis-aPerson. - Extensibility: Add new features without modifying existing code.
2. Syntax and Example
#include <iostream>
using namespace std;
class Person { // Base class
public:
string name;
int age;
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
class Employee : public Person { // Derived class
public:
int employee_id;
void showDetails() {
display(); // Reuses base class method
cout << "ID: " << employee_id << endl;
}
};
int main() {
Employee emp;
emp.name = "Ramesh";
emp.age = 30;
emp.employee_id = 101;
emp.showDetails();
return 0;
}
Output:
Name: Ramesh, Age: 30
ID: 101
Visual Trace: Memory Layout
classDiagram
class Person {
-string name
-int age
+display()
}
class Employee {
-int employee_id
+showDetails()
}
Person <|-- Employee : Inherits from3. Types of Inheritance
| Type | Definition | Example | Pros | Cons |
|---|---|---|---|---|
| Single | One base → one derived class. | class Car : public Vehicle |
Simple, easy to debug. | Limited flexibility. |
| Multilevel | Chain of inheritance (A→B→C). | Person → Employee → Manager |
Logical hierarchy (e.g., org charts). | Deep inheritance can be complex. |
| Hierarchical | One base → multiple derived classes. | Vehicle → Car, Bike, Truck |
Models shared traits (e.g., transport). | Base class changes affect all. |
| Multiple | One derived class inherits from two bases. | class AndroidPhone : public Phone, public MediaPlayer |
Combines features (e.g., phone + music). | Diamond problem risk. |
| Hybrid | Mix of multiple types (e.g., single + multiple). | Vehicle → Car → ElectricCar (also inherits from Battery). |
Flexible for complex systems. | Hard to maintain. |
4. The Diamond Problem & Solution
Problem: When a derived class inherits from two classes that both inherit from the same base, ambiguity arises.
classDiagram
class A {
+show()
}
class B {
+show()
}
class C {
+show()
}
class D {
+show()
}
A <|-- B
A <|-- C
B <|-- D
C <|-- D
D --> A : Ambiguous!Solution: Virtual Inheritance
class A {
public:
int x;
};
class B : virtual public A {}; // Virtual inheritance
class C : virtual public A {};
class D : public B, public C {};
int main() {
D obj;
obj.x = 10; // No ambiguity!
cout << obj.x;
return 0;
}
Key Point: Use virtual in the first inheritance to ensure a single copy of the base class.
5. Real-World Applications
Example 1: Khalti’s Payment System
- Base Class:
PaymentMethod(fields:amount,transactionId). - Derived Classes:
CreditCardPayment(addscardNumber,expiryDate).BankTransfer(addsaccountNumber).
- Why? Reuses common logic (e.g.,
calculateFee()) while extending for specific methods.
Example 2: Ncell’s Billing
- Base Class:
Customer(fields:name,phoneNumber). - Derived Classes:
PrepaidCustomer(addsbalance,topUp()).PostpaidCustomer(addsbillingCycle,generateBill()).
- Why? Avoids duplicating
Customerdata for each plan type.
Example 3: Daraz’s Order Processing
- Base Class:
Order(fields:orderId,customerId,status). - Derived Classes:
FoodOrder(addsdeliveryTime,restaurantId).ElectronicsOrder(addswarrantyPeriod).
- Why? Shared methods like
updateStatus()are inherited, reducing code.
6. Worked Example: Bank Loan System
Scenario: A bank offers Loan (base) with types HomeLoan and CarLoan (derived). Both need calculateInterest() but have different rates.
#include <iostream>
using namespace std;
class Loan {
protected:
double principal;
int years;
public:
Loan(double p, int y) : principal(p), years(y) {}
virtual double calculateInterest() = 0; // Pure virtual → abstract class
};
class HomeLoan : public Loan {
public:
HomeLoan(double p, int y) : Loan(p, y) {}
double calculateInterest() override {
return (principal * 0.08 * years); // 8% rate
}
};
class CarLoan : public Loan {
public:
CarLoan(double p, int y) : Loan(p, y) {}
double calculateInterest() override {
return (principal * 0.12 * years); // 12% rate
}
};
int main() {
HomeLoan hl(500000, 5);
CarLoan cl(200000, 3);
cout << "Home Loan Interest: " << hl.calculateInterest() << endl;
cout << "Car Loan Interest: " << cl.calculateInterest() << endl;
return 0;
}
Output:
Home Loan Interest: 200000
Car Loan Interest: 72000
Visual Trace: Object Creation
classDiagram
class Loan {
-principal
-years
+calculateInterest()
}
class HomeLoan {
+calculateInterest()
}
class CarLoan {
+calculateInterest()
}
Loan <|-- HomeLoan : Overrides
Loan <|-- CarLoan : Overrides7. Advantages and Disadvantages
| Advantages | Disadvantages |
|---|---|
| Code Reusability: Reduces duplication. | Complexity: Deep inheritance is hard to debug. |
| Extensibility: Easy to add features. | Tight Coupling: Changes in base class affect all derived classes. |
| Logical Modeling: Mirrors real-world hierarchies. | Performance Overhead: Virtual functions add slight runtime cost. |
| Polymorphism: Enables runtime method binding. | Diamond Problem: Requires careful design. |
8. Exam Tip
- Code Traces: Always show the state after each step (e.g., constructor calls in multilevel inheritance).
- UML Diagrams: Draw inheritance hierarchies for questions on types (e.g., "Design a system for a university with
Person → Student → Undergrad"). - Diamond Problem: Expect questions on virtual inheritance—explain why it’s needed.
- Real-World Links: Connect examples to banks (loans), e-commerce (orders), or telecom (billing).
- Key Terms: Define abstract classes, pure virtual functions, and access specifiers (
public/privateinheritance).
Practice Question:
Design a class hierarchy for a library system with Member (base) and StudentMember/FacultyMember (derived). Include a method borrowBook() overridden in each derived class. Draw the UML diagram and write the C++ code.
Based on the PU BE Computer (PU) syllabus for Object Oriented Programming in C++, unit 5.
Discussion
Loading…