Inheritance
Multilevel Inheritance
➢ In real systems, features often evolve step by step, not all at once.
➢ Reuses code from the previous level
➢ Adds only what is new or more specific
➢ Keeps the design clean and logically layered
Why this matters in practice:
Reduces code duplication
Makes maintenance easier (changes at higher levels automatically flow down)
Reflects real-world hierarchies clearly
Improves readability and extensibility of large C++ projects
int main() {
// Creating an object of GraduateStudent and displaying its details
GraduateStudent gradStudent("Ravindra", 35, 8, "Computer Science", 8.3, "Artificial Intelligence");
// Display information of the Graduate Student
cout << "Graduate Student Information:" << endl;
[Link]();
return 0; Graduate Student Information:
}
Name: Ravindra
Age: 35
ID: 8
Department: Computer Science
GPA: 8.3
Research Topic: Artificial Intelligence
Code reuse: Graduate Student automatically gets features of both Person and
Student
Logical modeling: Matches how University functions
Easy extension: You can later add special students , Intern, etc.
Maintainability: Changes in Person affect all derived roles consistently
Multiple Inheritance
Multiple Inheritance
#include <iostream>
using namespace std;
class A
{
protected:
int a;
public:
void get_a(int n)
{
a = n;
}
};
Multiple Inheritance
class B
{
protected:
int b;
public:
void get_b(int n)
{
b = n;
}
};
Multiple Inheritance
class C : public A, public B
{
public:
void display()
{
std::cout << "The value of a is : " << a << std::endl;
std::cout << "The value of b is : " << b << std::endl;
cout << "Addition of a and b is : " << a + b;
}
};
The value of a is : 10
The value of b is : 20
Addition of a and b is : 30
Hybrid Inheritance
class D : public B, public C
{
protected:
int d;
public:
void mul()
{
get_a();
get_b();
get_c();
cout << "Multiplication of a,b,c is : " << a * b * c << endl;
}
};
int main()
{
D d;
[Link]();
return 0;
}
Output
20 30 40
Enter the value of 'a' :
Enter the value of 'b' :
Enter the value of c is :
Multiplication of a,b,c is : 24000
Hierarchical Inheritance
Output
30 20
40 50
Enter the length and breadth of a rectangle:
Area of the rectangle is : 600
Enter the base and height of the triangle:
Area of the triangle is : 1000
Friend Function
friend function
If a function is defined as a friend function in C++, then the protected and
private data of a class can be accessed using the function
By using the keyword friend, compiler knows the given function is a friend
function
For accessing the data, the declaration of a friend function should be there
inside the body of a class starting with the keyword friend
friend function
class class_name
{
friend data_type function_name(argument/s);
// syntax of friend function.
};
➢ The friend function is preceded by the keyword friend
➢ The function can be defined anywhere in the program like a normal C++
function
➢ The function definition does not use either the keyword friend or scope
resolution operator
friend function
#include <iostream>
using namespace std;
class Box
{
private:
int length;
public:
Box() : length(0) { } // Constructor
// friend function
friend int printLength(Box);
};
int printLength(Box b) // Defining the function outside the class like normal function
{
[Link] += 10; // friend function is accessing the private data length
return [Link];
}
friend function
int main()
{
Box b; // Constructor will be called and length will be initialized to 0
cout << "Length of box: " <<
printLength(b) << endl; // 10 will be added to length to 0
return 0;
}
Output
Length of box: 10
Case Study : Secure Banking System: Bank Account and Audit System
Customer account details are strictly private :Normal application components must never
see
or modify:
Account balance
Transaction history
Internal flags (frozen, suspicious, ….etc)
An external audit system (used by regulators or internal compliance teams) must be able to:
Read exact balances
Inspect full transaction logs
Perform integrity checks
Do this without exposing data publicly and without becoming a subtype of Bank
Account as: auditors are not bank accounts, and they are not customers.
Why access specifiers and inheritance fail here
1. Making data public
Violates encapsulation
Any part of the program can access sensitive data
Security risk
2. Using protected + inheritance
Audit System is not a specialized Bank Account
Inheritance implies “is-a” relationship, which is false leads to conceptual design error
An auditor is not a bank account.
3. Getter functions
Exposes sensitive internals permanently
Even non audit code can misuse them
Breaks least privilege principle
Solution : Design using friend class
➢ Bank Account keeps everything private
➢Only Audit System is allowed special access
➢Access is explicit, limited, and intentional