π§ Mastering OOPs
A beginner-friendly and visually explained guide to Object-Oriented Programming in C++ β covering classes, inheritance, polymorphism, and more.

Full-Stack Developer | React & Django Enthusiast | DSA Enthusiast Passionate about building scalable web apps with modern tech. Currently exploring Django for backend magic and crafting sleek UIs with React. Writing about what I learn to help others on the same journey.
Iβve poured my hours of learning into this short and beginner-friendly Blog
OOPs
Object-Oriented Programming (OOPs) is a programming paradigm (style of coding) where most of the code revolves around objects and classes.
π Pillars of OOP
Abstraction
Encapsulation
Inheritance
Polymorphism

β 1. Class and Object
Class: A class is a user-defined data type that serves as a blueprint for creating objects. It defines both the structure and behaviour of objects through data members and member functions.
Object: An object is an instance of a class that represents a real-world entity and contains actual data.
π Notes:
A class does not occupy memory until an object is created from it.
An empty class (a class with no data members or functions) still takes 1 byte of memory.
The size of a class object depends on its data members and may include padding for memory alignment.
class Car { // Class definition
string name;
string brandName;
int manufacturingYear;
};
Car c1; // Object of class Car
π« 2. Abstraction
Abstraction means hiding the internal implementation details and exposing only the essential features to the user.
β Key Idea:
Users should not need to understand how things work internally β they should just know how to use it. If anyone know then it is fine but not necessary.
π Achieved by:
Keeping data private
Exposing only a public interface (functions)
π Real-Life Analogy:
If a user wants to turn on the TV, we donβt ask them to connect red and green wiresβwe just provide a simple "Power" button.
class Television {
private:
bool isOn;
int currentChannel;
int currentVolume;
string brand;
public:
void TurnOn(); // Turns the TV on
void TurnOff(); // Turns the TV off
void VolumeUp(); // Increases the volume
void VolumeDown(); // Decreases the volume
~Television() {} // Destructor
};
π 3. Encapsulation
Encapsulation refers to wrapping data and methods that operate on that data into a single unit (i.e., a class). It also helps in data protection by restricting direct access to internal variables.
β Key Idea:
Make data members private
Use public getter and setter functions to access and modify them
π― Benefits:
Protects data from unauthorized access or misuse
Improves code maintainability and security
class Engineer {
private:
// These variables can't be accessed directly from outside the class
string name;
string role;
int yearOfExperience;
public:
// Setter methods
void setName(string a) { name = a; }
void setRole(string r) { role = r; }
void setExperience(int year) { yearOfExperience = year; }
// Getter methods
string getName() { return name; }
string getRole() { return role; }
int getExperience() { return yearOfExperience; }
};
// Creating an object of class Engineer
Engineer E1;
π Access Modifiers
Access modifiers determine the visibility of class members (variables and functions).
| Modifier | Description |
public | Accessible from anywhere β inside or outside the class. |
private | Accessible only within the class. Not accessible from outside. |
protected | Accessible within the class and its derived (child) classes. |
βοΈ Getters & Setters
Getter: A function used to access private data members from outside the class.
Setter: A function used to set or initialize private data members from outside the class.
π They provide controlled access to class variables and help in maintaining data integrity.
π οΈ Constructor
A constructor is a special function that is automatically invoked when an object of a class is created.
β Key Points:
Its name is the same as the class name.
It has no return type (not even
void).Used to initialize objects.
There are different types:
Default Constructor
Parameterized Constructor
Copy Constructor
class Engineer {
private:
string name;
string role;
int yearOfExperience;
public:
Engineer(){} // default constructor
// Parameterized Constructor
Engineer(string name, string role, int year) {
this->name = name;
this->role = role;
this->yearOfExperience = year;
}
};
// Object creation
Engineer e1("Satyendra", "Software Developer", 1);
π§Ή Destructor
A destructor is a special function that is automatically called when an object goes out of scope or is explicitly deleted.
β Key Points:
Used to release resources acquired by the object.
Its name is the same as the class name, prefixed with a tilde
~.It does not take parameters and does not return anything.
You usually donβt need to write one unless you're managing memory manually (e.g., using
new/delete).
class Engineer {
private:
string name;
string role;
int yearOfExperience;
public:
Engineer(){} // default constructor
public:
~Engineer() {
cout << "Engineer object destroyed" << endl;
}
};
π 4. Inheritance
Inheritance is a feature of OOP that allows a class to acquire properties and behaviors (i.e., data members and methods) from another class.
β Key Idea:
One class (child/derived) inherits from another class (parent/base) to promote code reusability.
class Car { // Base class (Parent)
protected: // Accessible to derived classes
string name;
string brandName;
int manufacturingYear;
public:
void startEngine() {
cout << "Engine started" << endl;
}
void stopEngine() {
cout << "Engine stopped" << endl;
}
};
class PetrolCar : public Car {
// Inherits all public & protected members from Car
// You can also add extra features here
};
class DieselCar : public Car {
// Inherits all public & protected members from Car
};
π’ Types of Inheritance in C++
| Type | Description |
| Single | One class inherits from one base class. class PetrolCar : public Car |
| Multilevel | A class inherits from a derived class. ModernCar β PetrolCar β Car |
| Multiple | A class inherits from more than one base class. class A : public B, public C |
| Hierarchical | Multiple classes inherit from the same base class. PetrolCar, DieselCar β Car |
| Hybrid | Combination of two or more types of inheritance. |
| Diamond Problem | Occurs in multiple inheritance when two base classes inherit from a common ancestor, causing ambiguity. Solved using virtual inheritance. |
π 5. Polymorphism
Polymorphism means "one name, many forms".
It allows the same function or operator to behave differently based on the context.
π― Real-Life Analogy:
In MS Paint, the selector tool can perform multiple actions like draw, erase, or move depending on the object β one tool, many actions.
π’ Types of Polymorphism in C++
| Type | Description | Example |
| Compile-Time (Static) | Function resolution happens at compile time | Function/Operator Overloading |
| Run-Time (Dynamic) | Function resolution happens at runtime using virtual | Function Overriding |
βοΈ Compile-Time Polymorphism
β Function Overloading
Multiple functions with the same name but different parameters.
class Car {
private:
bool isEngineOn;
int currentGear;
public:
void changeGear() {
cout << "Gear changed automatically" << endl;
}
void changeGear(int gear) {
currentGear = gear;
cout << "Gear changed to " << gear << endl;
}
~Car() {
cout << "Car object destroyed" << endl;
}
};
β Operator Overloading
Redefining built-in operators for user-defined types (like + for complex numbers).
class Complex {
private:
int real;
int imaginary;
public:
Complex(int real = 0, int img = 0) : real(real), imaginary(img) {}
void Display() {
cout << "Complex number: " << real << " + i" << imaginary << endl;
}
// Overloading + operator
Complex operator + (const Complex &c) {
Complex temp;
temp.real = real + c.real;
temp.imaginary = imaginary + c.imaginary;
return temp;
}
};
βοΈ Run-Time Polymorphism
𧬠Function Overriding (Run-Time Polymorphism)
To achieve run-time polymorphism, we use function overriding, where a derived class provides its own version of a function that is already defined in the base class.
β Key Requirement
The base class function must be marked with the virtual keyword to allow dynamic dispatch at runtime.
π Real-World Analogy:
Different animals make different sounds. We call Speak(), but each animal "speaks" in its own way β same interface, different behavior.
class Animal {
public:
virtual void Speak() {
cout << "Animal Speaking." << endl;
}
virtual ~Animal() {
cout << "Animal Destructor" << endl;
}
};
class Dog : public Animal {
public:
void Speak() override {
cout << "Bhou Bhou Bhoooooo" << endl;
}
~Dog() {
cout << "Dog Destructor" << endl;
}
};
π§ Why Use Virtual Destructors?
When deleting a derived class object through a base class pointer, having a virtual destructor ensures that both destructors (derived β base) get called.
Without it, only the base class destructor may run β leading to resource leaks.
π§± Abstract Class
An abstract class is a class that contains at least one pure virtual function.
β Key Points:
Acts as a blueprint for other classes.
Cannot be instantiated (i.e., you cannot create objects of an abstract class).
Derived classes must override all pure virtual functions to be concrete.
class Car {
protected:
bool isEngineOn;
string name;
public:
Car(string name) : name(name), isEngineOn(false) {}
void StartEngine() {
isEngineOn = true;
cout << "Car Engine started" << endl;
}
void StopEngine() {
isEngineOn = false;
cout << "Car Engine stopped" << endl;
}
// Pure virtual functions
virtual void ChangeGear() = 0;
virtual void Accelerate() = 0;
virtual ~Car() {
cout << "Car Destructor" << endl;
}
};
π§© Interface in C++
An interface is a class where all functions are pure virtual.
Itβs used to define a contract β what a class must do, without saying how.
β Notes:
You canβt create an object of an interface.
A class that implements
ICarmust define all functions.Though C++ doesnβt have a formal
interfacekeyword like Java or C#, we achieve the same with pure virtual classes.
class ICar {
public:
virtual void StartEngine() = 0;
virtual void StopEngine() = 0;
virtual void ChangeGear() = 0;
virtual void Accelerate() = 0;
virtual ~ICar() {
cout << "ICar Destructor" << endl;
}
};
π₯ Friend Function
A friend function is a non-member function that is given special access to the private and protected members of a class.
β Key Points:
Declared using the
friendkeyword inside the class.It is not a member, but it acts like one.
Often used when external functions need access to internal data.
class Customer {
private:
string name;
int balance;
public:
Customer(const string &name, int balance) : name(name), balance(balance) {}
// Friend function declaration
friend void SeeBalance(Customer &c);
~Customer() {
cout << "Destructor called for " << name << endl;
}
};
// Friend function definition (outside the class)
void SeeBalance(Customer &c) {
cout << "The balance is: " << c.balance << endl;
}
π§βπ€βπ§ Friend Class
A friend class is a class that is granted full access to another classβs private and protected members.
β Key Points:
Declared using
friend class ClassName;inside the class to be exposed.The friend class can access all private and protected members.
Useful in tight coupling scenarios where two classes work closely.
class Human {
private:
int age;
public:
void secret() {
cout << "This is a secret function in the Human class!" << endl;
}
// Granting access to Me class
friend class Me;
};
class Me {
public:
void DisplayAge(Human &ram) {
ram.age = 15;
ram.secret(); // Accessing private function
cout << "My age is: " << ram.age << endl;
}
};
π§ When to Use Friend Function/Class?
When tight internal access is needed between two classes.
In operator overloading where access to private members is required.
In helper functions that logically operate on the internal state of a class.
π§· Static Data Members
A static data member is a member of a class that is shared among all objects of that class.
β Key Points:
Declared using the
statickeyword.It is not tied to any specific object, but to the class itself.
It is shared and retains its value across all object instances.
Can be accessed using the class name (without creating an object).
π§ Real-Life Analogy:
In a Customer class, you want to keep track of the total number of customers and total balance across all accounts β this is a class-level property, not per-object.
class Customer {
private:
static int total_balance;
static int total_account;
public:
// Static member function to access static data
static void AccessTotalAccount() {
// Cannot access non-static members here
cout << "Total accounts: " << total_account << endl;
cout << "Total balance in Bank: " << total_balance << endl;
}
~Customer() {
// Destructor logic (if needed)
}
};
// Static member definition outside the class
int Customer::total_balance = 0;
int Customer::total_account = 0;
π§ Static Member Functions
A static member function is a class function that:
Can be called using the class name (no object needed).
Can only access static data members (not instance variables).
π‘ Why Use It?
To manipulate or access static data members
To create utility functions that operate at the class level
class Customer
{
private:
static int total_balance;
static int total_account; // static data member
public:
// static member function
static void AccessTotalAccount()
{
// this function can't access non-static data types
cout << "Total account " << total_account << endl;
cout << "Total balance in Bank " << total_balance << endl;
}
// destructor
~Customer()
{
/
}
};
Customer::AccessTotalAccount(); // No object needed
β οΈ Notes:
Static functions cannot use
thispointer.Static members must be defined outside the class once (memory is allocated here).
Static data is common to all objects, useful for counting, pooling, logging, etc
π¨βπ» About the Author
I am Satyendra Gautam a passionate programmer and self-learner who believes in mastering concepts by teaching others. With a strong focus on clean code, real-world analogies, and beginner-friendly explanations.
I enjoys working with C++, full-stack development (React + Django), and believes in building educational resources that are as practical as they are readable.
"Learning is most powerful when shared. This guide is my way of giving back to the community." β Satyendra Gautam
π GitHub: https://github.com/satyendragautam901
π LinkedIn: https://www.linkedin.com/in/satyendra-gautam-525220244/
π Follow Tech Insights by Gautam for more on React, Django, and practical dev tips.
#ReactJS #Django #WebDev #TechInsightsByGautam #DSA #BeginnerFriendly




