Inheritance is the most powerful concept of Object Oriented Programming (OOP).
Inheritance means access the properties and features of one class into another class.
( Or )
Deriving new class/classes from existing old class/classes.
Base class: The class who is going to provide its features to another class will be called base class
Derived Class: The class who is using the properties and features of another class will be called derived class.
Advantage of Inheritance:
Reusability - facility to use public methods of base class without rewriting the same
Extensibility - extending the base class logic as per business logic of the derived class.
Data hiding -base class can decide to keep some data private so that it cannot be altered by the derived class
Syntax
class subclass_name : visibility mode superclass_name
{
// data members
// methods
}
Access modifiers defines the scope of members of BaseClass into DerivedClass.
C++ supports the followling access modifiers:
Private Modifier
Protected Modifier
Public Modifier
Private Modifier: The scope of private members are restricted to its own class. Private members can't be accessed by the derived class or in main() function.
Protected Modifier: The scope of protected members are restricted to its own class and derived class. Protected members can be accessed by the derived class but they can't be accessed in main() function.
Public Modifier: Public members can be accessed by its own class, derived class and in main() function.
Types of Inheritance
Based on number of ways inheriting the feature of base class into derived class it have five types they are:
Single inheritance
Multiple inheritance
Hierarchical inheritance
Multiple inheritance
Hybrid inheritance
A derived class with only one base class is called single inheritance. (i.e. one sub class is inherited by one base class only.)
Single inheritance
#include <iostream>
#include <conio.h>
using namespace std;
class P {
public:
void peacock() {
cout << "Animal" << endl;
}
};
class Q : public P {
public:
void parrot() {
cout << "Bird" << endl;
}
};
void main() {
Q obj;
obj.peacock();
obj.parrot();
getch();
}
Output:
Animal
Bird
A derived class with multiple base class is called multiple inheritance. (i.e. . i.e one sub class is inherited from more than one base classes.)
Syntax
class subclass_name : access_mode base_class1, access_mode base_class2, ....
{
//body of subclass
};
Multiple inheritance
#include <iostream>
#include <conio.h>
using namespace std;
class P {
public:
void peacock() {
cout << "Animal" << endl;
}
};
class R {
public:
void parrot() {
cout << "Bird" << endl;
}
};
class Q : public P, public R {
public:
void penguin() {
cout << "It is also a bird" << endl;
}
};
void main() {
Q obj;
obj.peacock(); // Function from class P
obj.parrot(); // Function from class R
obj.penguin(); // Function from class Q
getch();
}
Output:
Animal
Bird
It is also a bird
Multiple derived classes with same base class is called hierarchical inheritance. (i.e.more than one sub class is inherited from a single base class.)
Syntax
class base_class
{
... .. ...
};
class first_derived_class: public base_class
{
... .. ...
};
class second_derived_class: public base_class
{
... .. ...
};
class third_derived_class: public base_class
{
... .. ...
};
Hierarchical Inheritance:
#include <iostream>
#include <conio.h>
using namespace std;
class P {
public:
void peacock() {
cout << "Animal" << endl;
}
};
class R : public P {
public:
void parrot() {
cout << "Bird" << endl;
}
};
class Q : public P {
public:
void penguin() {
cout << "It is also a bird" << endl;
}
};
void main() {
R obj1;
obj1.peacock(); // Function from class P
obj1.parrot(); // Function from class R
Q obj2;
obj2.peacock(); // Function from class P
obj2.penguin(); // Function from class Q
getch();
}
Output:
Animal
Bird
Animal
It is also a bird
In this one class is inherit from base class. Then this derived class becomes base class of another class. Thus the class in center is called Intermediate class.
In other words, deriving a class from a derived class is known as multi-level inheritance.
Simple multi-level inheritance is shown in below image where Class A is a parent of Class B and Class B is a parent of Class C
Multi-level Inheritance
#include <iostream>
#include <conio.h>
using namespace std;
class P {
public:
void peacock() {
cout << "Animal" << endl;
}
};
class R : public P {
public:
void parrot() {
cout << "Bird" << endl;
}
};
class Q : public R {
public:
void penguin() {
cout << "It is also a bird" << endl;
}
};
void main() {
Q obj;
obj.peacock(); // Function from class P
obj.parrot(); // Function from class R
obj.penguin(); // Function from class Q
getch();
}
Output:
Animal
Bird
It is also a bird
Combination of multiple and hierarchical inheritance is called hybrid inheritance. (i.e. Combination of any inheritance type )
Hybrid Inheritance
#include <iostream>
#include <conio.h>
using namespace std;
class P {
public:
void peacock() {
cout << "Animal" << endl;
}
};
class R : public P {
public:
void parrot() {
cout << "Bird" << endl;
}
};
class S {
public:
void sparrow() {
cout << "Small Bird" << endl;
}
};
class Q : public R, public S {
public:
void penguin() {
cout << "It is also a bird" << endl;
}
};
void main() {
Q obj;
obj.peacock(); // Function from class P
obj.parrot(); // Function from class R
obj.sparrow(); // Function from class S
obj.penguin(); // Function from class Q
getch();
}
Output
Animal
Bird
Small Bird
It is also a bird
An operator is a symbol that tells the compiler to perform specific task.
Every operator have their own functionality to work with built-in data types. Class is user-defined data type and compiler doesn't understand, how to use operators with user-defined data types.
To use operators with user-defined data types, they need to be overload according to a programmer's requirement.
Operator overloading is a way of providing new implementation of existing operators to work with user-defined data types.
An operator can be overloaded by defining a function to it. The function for operator is declared by using the operator keyword followed by the operator.
There are some operators cannot be overloaded that are given below:
:: Scope resolution operator.
. Class membership operator.
ternary or conditional operator.
pointer to member operator.
->* pointer to member operator
sizeof()
To overload an operator a special operator function is defined inside the class
returntype operator symbol(parameters)
{
//function body
}
To overload an operator a special operator function is defined outside the class
returntype classname :: operator symbol(parameters)
{
//function body
}
There are two types of operator overloading in C++
Binary Operator Overloading
Unary Operator Overloading
Binary operator is an operator that takes two operand (variable). Binary operator overloading is similar to unary operator overloading except that a binary operator overloading requires an additional parameter.
Binary Operators
• Arithmetic operators (+, -, *, /, %)
• Arithmetic assignment operators (+=, -=, *=, /=, %=)
• Relational operators (>, <, >=, <=, !=, ==)
Simple Addition in C++ Binary Operator Overloading Program
#include<iostream>
using namespace std;
class binaryol
{
int x;
public:
void getdata(int a)
{
x=a;
}
void operator +(binaryol &ob)
{
int m;
m = x + ob.x;
cout<<"sum="<<m;
}
};
int main()
{
binaryol b1, b2;
b1.getdata(10);
b2.getdata(20);
b1+b2;
}
Output:
sum=30
Unary operator is an operator that takes single operand(variable). Both increment(++) and decrement(--) operators are unary operators.
Unary increment (++) and decrement (--) operator overloading program in c++.
#include<iostream>
using namespace std;
class Test
{
int a;
public:
void read() //function to read
{
a=0;
}
void show() //function to display
{
cout<<"a = "<<a<<endl;
}
void operator++() //unary ++ operator overloading
{
a++;
}
void operator --() //unary -- operator overloading
{
a--;
}
};
int main()
{
Test T;
T.read();
T.show();
++T;
T.show();
--T;
T.show();
}
Output:
a=0
a=1
a=0
In C++, pointers are variables that store the memory address of another variable. Instead of holding data itself, they hold the address of where the data is stored in memory.
Pointer Variable: A variable that stores the address of another variable.
Dereferencing: Accessing the value stored at the memory address a pointer points to.
Address-of Operator (&): Used to get the memory address of a variable.
Pointer Declaration: A pointer is declared using the * symbol.
Example program:
#include <iostream>
using namespace std;
int main() {
int num = 10; // A normal integer variable
int* ptr = # // Pointer 'ptr' holds the address of 'num'
cout << "Value of num: " << num << endl; // Directly printing the value of num
cout << "Address of num: " << &num << endl; // Printing the address of num
cout << "Pointer ptr holds the address: " << ptr << endl; // Pointer holds address of num
cout << "Dereferencing ptr to get the value: " << *ptr << endl; // Dereferencing ptr to get the value of num
return 0;
}
Output:
Value of num: 10
Address of num: 0x7ffeb1d7f53c // (address may vary)
Pointer ptr holds the address: 0x7ffeb1d7f53c // Same as address of num
Dereferencing ptr to get the value: 10
int num = 10;: We declare a variable num and assign it a value of 10.
*int ptr = #**: We declare a pointer ptr that holds the address of num. The & operator is used to get the address of num.
cout << #: Prints the address of num.
cout << *ptr;: This prints the value stored at the address pointed to by ptr (dereferencing the pointer), which is the value of num (10).
In simple terms:
A pointer stores the location (memory address) of a variable.
By dereferencing the pointer (using *), we can access the value stored at that location.
Pointers are powerful in C++ because they allow us to manipulate memory directly, which is useful for efficient memory management and dynamic data structures.
The dereference operator in C++ is represented by the * symbol and is used to access the value stored at the memory address that a pointer is pointing to.
A pointer holds the memory address of a variable, not the value itself.
The dereference operator (*) is used to access the actual value stored at that memory address.
The pointer contains the address of a variable.
The dereference operator (*) accesses the value stored at that address.
Example program
#include <iostream>
using namespace std;
int main() {
int num = 10; // Declare an integer variable
int* ptr = # // Pointer 'ptr' holds the address of 'num'
// Print the value stored at the address pointed to by ptr
cout << "Value at the address ptr is pointing to: " << *ptr << endl; // Dereferencing ptr
return 0;
}
Output:
Value at the address ptr is pointing to: 1
int* ptr = # – The pointer ptr holds the address of num.
*ptr – The dereference operator is used to access the value stored at the address ptr is pointing to, which is 10.
A pointer is like a street address.
The dereference operator is like going to that address and retrieving the house (the value) located at that address.