My Blog
All Posts
Object Oriented Programming
21 January 2025
Lesson 1: Fundamentals of Object-Oriented
Programming (OOP)
What is Object-Oriented Programming?
Object-Oriented Programming (OOP) is a programming paradigm that models real-world
entities using classes and objects. It focuses on organizing code into reusable components,
making programs more modular, maintainable, and scalable.
Key Concepts of OOP
Encapsulation: Wrapping data and methods into a single unit (class).
Example: Protecting data using private members.
Abstraction: Hiding unnecessary details and exposing only essential features.
Example: Using a Car class without knowing the engine's internal details.
Inheritance: Creating new classes from existing ones to promote code reuse.
Example: A Dog class inheriting from an Animal class.
Polymorphism: Ability to process objects differently based on their data type.
Example: Overloading functions or overriding methods.
Code Example
#include <iostream>
using namespace std;
// Class representing a Car (Encapsulation)
class Car {
private:
string brand; // Data hiding
int speed;
public:
// Constructor to initialize the car's attributes
Car(string carBrand, int carSpeed) {
brand = carBrand;
speed = carSpeed;
// Method to display car details (Abstraction)
void displayDetails() {
cout << "Brand: " << brand << ", Speed: " << speed << " km/h" << endl;
// Method to increase speed
void accelerate(int increment) {
speed += increment;
cout << "The car accelerates. New Speed: " << speed << " km/h" << endl;
};
int main() {
// Creating objects (real-world entities)
Car car1("Toyota", 100);
Car car2("Honda", 120);
// Using methods of the Car class
[Link]();
[Link](20);
[Link]();
[Link](30);
return 0;
Explanation
Encapsulation:
Data members (brand and speed) are private, ensuring they can't be accessed directly.
Public methods (displayDetails and accelerate) provide controlled access.
Abstraction: The user interacts with the Car class through public methods without
needing to know how the speed is stored or updated.
Objects: car1 and car2 are instances of the Car class, representing individual cars.
Reusability: The same Car class can be used to create multiple car objects with
different properties.
Key Takeaways
OOP organizes programs using classes and objects.
Key principles like encapsulation and abstraction ensure better data management
and usability.
Objects act as real-world entities, encapsulating data and behavior.
Assignment
Create a class named Book with the following:
1. Private attributes: title, author, price.
2. A constructor to initialize the attributes.
3. A method displayDetails() to show book details.
4. Create and display details of two Book objects in the main() function.
Lesson 2: Classes and Objects in C++
What Are Classes and Objects?
Class: A blueprint for creating objects. It defines properties (attributes) and
behaviors (methods).
Object: An instance of a class. It represents a real-world entity with data
and functionality.
Key Points
1. Defining a Class:
Syntax: class ClassName { /* members */ };
Members can be data members (variables) or member functions (methods).
1. Creating Objects:
Syntax: ClassName objectName;
Objects access class members using the . operator.
Code Example: Student Class
#include <iostream>
using namespace std;
// Defining a class
class Student {
private:
string name;
int rollNumber;
float marks;
public:
// Member function to initialize attributes
void setDetails(string studentName, int studentRoll, float studentMarks)
name = studentName;
rollNumber = studentRoll;
marks = studentMarks;
// Member function to display details
void displayDetails() {
cout << "Name: " << name << endl;
cout << "Roll Number: " << rollNumber << endl;
cout << "Marks: " << marks << endl;
};
int main() {
// Creating objects of the Student class
Student student1, student2;
// Setting details for each object
[Link]("Alice", 101, 95.5);
[Link]("Bob", 102, 89.0);
// Displaying details of each student
cout << "Details of Student 1:" << endl;
[Link]();
cout << "\nDetails of Student 2:" << endl;
[Link]();
return 0;
Explanation
1. Class Definition:
The Student class encapsulates data (name, rollNumber, marks) and methods
(setDetails, displayDetails).
1. Object Creation:
student1 and student2 are objects of the Student class.
Each object has its own copy of the attributes defined in the class.
1. Accessing Members:
The setDetails method assigns values to the attributes.
The displayDetails method outputs the data of the object.
Key Takeaways
A class is a blueprint, while an object is an instance of the class.
Use member functions to interact with and manipulate an object’s data.
The . operator allows access to the class members through objects.
Assignment
Create a class Employee with the following:
1. Private attributes: name, id, salary.
2. Public methods:
setDetails(): Accepts and sets the attributes.
displayDetails(): Displays the employee's details.
1. Create three employee objects, set their details, and display them in the
main() function.
Lesson 3: Constructors and Destructors in C++
What Are Constructors and Destructors?
Constructor: A special member function that is automatically invoked when an object
is created. It initializes the object.
Destructor: A special member function that is automatically invoked when an object
goes out of scope or is deleted. It cleans up resources.
Key Points
1. Constructor:
Has the same name as the class.
Does not have a return type.
Can be default, parameterized, or copy constructor.
Can be overloaded.
1. Destructor:
Has the same name as the class, prefixed with ~.
Cannot be overloaded.
Used to free resources (e.g., memory, file handles).
Code Example: BankAccount Class
#include <iostream>
using namespace std;
class BankAccount {
private:
string ownerName;
double balance;
public:
// Constructor: Initializes the object
BankAccount(string name, double initialBalance) {
ownerName = name;
balance = initialBalance;
cout << "Account created for " << ownerName << " with balance: $" <<
// Method to deposit money
void deposit(double amount) {
balance += amount;
cout << "Deposited $" << amount << ". New balance: $" << balance << e
// Method to withdraw money
void withdraw(double amount) {
if (amount > balance) {
cout << "Insufficient balance!" << endl;
} else {
balance -= amount;
cout << "Withdrew $" << amount << ". Remaining balance: $" << bal
}
}
// Destructor: Cleans up resources
~BankAccount() {
cout << "Account for " << ownerName << " is being deleted." << endl;
};
int main() {
// Creating a BankAccount object
BankAccount account("Alice", 500.0);
// Performing operations
[Link](200.0);
[Link](100.0);
// Destructor will be called automatically when the program ends
return 0;
Explanation
Constructor:
Automatically called when the object account is created.
Initializes the ownerName and balance.
Destructor:
Automatically called when the object account goes out of scope (at the end of main).
Outputs a message indicating that the account is being deleted.
Reusability: The class can be reused to create multiple accounts with unique data.
Key Takeaways
Constructors ensure that objects are initialized properly.
Destructors handle cleanup, preventing resource leaks.
They work automatically, making object lifecycle management easier.
Assignment
1. Create a class Rectangle with:
Attributes: length and width (private).
A constructor to initialize these attributes.
A method area() to calculate and display the area.
A destructor to display a message when the object is deleted.
1. In the main() function:
Create two Rectangle objects with different dimensions.
Display their areas.
Lesson 4: Copy Constructors and Assignment
Operators in C++
What Are Copy Constructors and Assignment Operators?
Copy Constructor: A special constructor that initializes an object by copying data from
another object of the same class.
Assignment Operator: Used to assign the values of one object to another already
existing object.
Key Points
1. Copy Constructor:
Syntax: ClassName(const ClassName &obj);
Automatically invoked when:
An object is initialized with another object.
An object is passed by value to a function.
An object is returned by value from a function.
1. Assignment Operator:
Syntax: ClassName& operator=(const ClassName &obj);
Used when assigning values between two objects after they are created.
Needs to be defined explicitly for deep copies (e.g., dynamic memory allocation).
Code Example: Copy Constructor and Assignment Operator
#include <iostream>
#include <cstring>
using namespace std;
class Person {
private:
char* name;
int age;
public:
// Constructor
Person(const char* personName, int personAge) {
name = new char[strlen(personName) + 1];
strcpy(name, personName);
age = personAge;
cout << "Person object created for " << name << endl;
// Copy Constructor
Person(const Person &other) {
name = new char[strlen([Link]) + 1];
strcpy(name, [Link]);
age = [Link];
cout << "Copy constructor called for " << name << endl;
// Assignment Operator
Person& operator=(const Person &other) {
if (this != &other) { // Prevent self-assignment
delete[] name; // Clean up existing memory
name = new char[strlen([Link]) + 1];
strcpy(name, [Link]);
age = [Link];
cout << "Assignment operator called for " << name << endl;
return *this;
// Method to display details
void display() const {
cout << "Name: " << name << ", Age: " << age << endl;
}
// Destructor
~Person() {
cout << "Destructor called for " << name << endl;
delete[] name;
};
int main() {
// Using the constructor
Person person1("Alice", 25);
// Using the copy constructor
Person person2 = person1; // Copy constructor is called
// Using the assignment operator
Person person3("Bob", 30);
person3 = person1; // Assignment operator is called
// Display details of all objects
[Link]();
[Link]();
[Link]();
return 0;
Explanation
Constructor: Initializes name and age using dynamic memory allocation.
Copy Constructor:
Creates a deep copy of the name to avoid shared memory issues.
Copies the value of age.
Assignment Operator:
Handles cleanup of existing memory (via delete[]) before copying.
Performs deep copy of name and assigns age.
Destructor: Releases the dynamically allocated memory for name.
Key Takeaways
Use copy constructors and assignment operators to handle deep copies for classes
with dynamic memory.
Always include checks (e.g., if (this != &other)) to prevent self-assignment in the
assignment operator.
Ensure proper memory management with constructors, destructors, and
assignment operators.
Assignment
Create a class Book with the following:
Attributes: title (dynamically allocated) and price.
Methods:
Constructor to initialize attributes.
Copy constructor for deep copying.
Assignment operator for deep assignment.
Destructor to release memory.
In the main() function:
Create one Book object and initialize it.
Use the copy constructor to create another Book object.
Assign one Book object to another using the assignment operator.
Display the details of all Book objects.
Lesson 5: Static Members in C++
What Are Static Members?
Static Data Members: Variables shared among all objects of a class.
Only one copy of a static member exists, no matter how many objects are created.
Static Member Functions: Functions that can access only static data members.
Key Points
Static Data Members:
Declared using the static keyword inside the class.
Must be defined and initialized outside the class.
Shared across all objects of the class.
Static Member Functions:
Declared using the static keyword.
Can be called without creating an object (using ClassName::functionName()).
Can only access static data members or other static functions.
Code Example: Counter Class
#include <iostream>
using namespace std;
class Counter {
private:
static int count; // Static data member
public:
// Constructor increments count
Counter() {
count++;
}
// Static function to get count
static int getCount() {
return count;
};
// Define and initialize static data member
int Counter::count = 0;
int main() {
// Create objects of Counter
Counter c1, c2, c3;
// Call static function
cout << "Number of Counter objects: " << Counter::getCount() << endl;
return 0;
Explanation
Static Data Member:
count is declared as static and shared among all Counter objects.
It is defined and initialized outside the class (int Counter::count = 0;).
Static Member Function:
getCount() is a static function that returns the value of count.
It is called using Counter::getCount() without creating an object.
Object Behavior:
Each time a Counter object is created, the count variable increments.
Key Takeaways
Static members are shared across all objects of a class.
Use static functions to access and manipulate static data.
Static members can be accessed without creating an object.
Assignment
Create a class Student with the following:
Attributes:
name (non-static).
rollNumber (non-static).
studentCount (static, to track the number of students).
Methods:
Constructor: Initializes the name and rollNumber and increments studentCount.
Static function: getStudentCount() to return the total count of students.
In the main() function:
Create multiple Student objects.
Display the total number of students using the static function.
Lesson 6: Inheritance in C++
What is Inheritance?
Inheritance is an Object-Oriented Programming concept that allows a class (called derived
class) to inherit properties and methods from another class (called base class). It promotes
code reuse and enables hierarchical relationships between classes.
Types of Inheritance
Single Inheritance: A single derived class inherits from a single base class.
1. Multiple Inheritance: A derived class inherits from multiple base classes.
2. Multilevel Inheritance: A class inherits from another derived class.
3. Hierarchical Inheritance: Multiple derived classes inherit from a single base class.
4. Hybrid Inheritance: A combination of two or more types of inheritance.
Code Example: Single Inheritance
#include <iostream>
using namespace std;
// Base class
class Vehicle {
protected:
int speed;
public:
Vehicle(int s) : speed(s) {
cout << "Vehicle created with speed " << speed << " km/h" << endl;
void displaySpeed() {
cout << "Speed: " << speed << " km/h" << endl;
};
// Derived class
class Car : public Vehicle {
private:
string brand;
public:
Car(int s, string b) : Vehicle(s), brand(b) {
cout << "Car created of brand " << brand << endl;
}
void displayDetails() {
cout << "Car Brand: " << brand << ", ";
displaySpeed();
};
int main() {
Car myCar(150, "Toyota");
[Link]();
return 0;
Explanation
1. Base Class:
The Vehicle class contains a protected attribute speed and a public
method displaySpeed().
1. Derived Class:
The Car class inherits from Vehicle using public inheritance.
The Car class adds a new attribute brand and a method displayDetails().
1. Object Behavior:
The Car object has access to the Vehicle class's public and protected members.
Key Takeaways
Inheritance enables code reuse by allowing a derived class to inherit from a base class.
Use access specifiers (public, protected, private) to control member access in the
derived class.
Derived classes can add new attributes and methods while using the base
class's functionality.
Assignment
1. Implement a program with the following classes:
Base Class: Person
Attributes: name (protected)
Method: displayName() to display the name.
Derived Class: Student
Attributes: rollNumber (private).
Method: displayDetails() to display name and roll number.
2. In the main() function:
Create an object of the Student class and display its details.
Lesson 7: Types of Inheritance in C++
1. Single Inheritance
A single derived class inherits from one base class.
Example:
cppCopyEdit#include <iostream>
using namespace std;
// Base class
class Animal {
public:
void eat() {
cout << "This animal eats food." << endl;
}
};
// Derived class
class Dog : public Animal {
public:
void bark() {
cout << "The dog barks." << endl;
};
int main() {
Dog myDog;
[Link](); // Access base class method
[Link](); // Access derived class method
return 0;
2. Multiple Inheritance
A derived class inherits from more than one base class.
Example:
#include <iostream>
using namespace std;
// Base class 1
class Person {
public:
void showPerson() {
cout << "This is a person." << endl;
};
// Base class 2
class Employee {
public:
void showEmployee() {
cout << "This is an employee." << endl;
};
// Derived class
class Manager : public Person, public Employee {
public:
void showManager() {
cout << "This is a manager." << endl;
}
};
int main() {
Manager myManager;
[Link]();
[Link]();
[Link]();
return 0;
3. Multilevel Inheritance
A class inherits from a derived class, creating a chain of inheritance.
Example:
#include <iostream>
using namespace std;
// Base class
class LivingBeing {
public:
void breathe() {
cout << "Living beings breathe." << endl;
};
// Derived class
class Animal : public LivingBeing {
public:
void walk() {
cout << "Animals walk." << endl;
};
// Further derived class
class Bird : public Animal {
public:
void fly() {
cout << "Birds fly." << endl;
};
int main() {
Bird myBird;
[Link](); // Base class method
[Link](); // Intermediate class method
[Link](); // Derived class method
return 0;
4. Hierarchical Inheritance
Multiple derived classes inherit from a single base class.
Example:
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
void displayShape() {
cout << "This is a shape." << endl;
};
// Derived class 1
class Circle : public Shape {
public:
void area() {
cout << "Area of circle = πr²" << endl;
}
};
// Derived class 2
class Rectangle : public Shape {
public:
void area() {
cout << "Area of rectangle = length × breadth" << endl;
};
int main() {
Circle myCircle;
Rectangle myRectangle;
[Link]();
[Link]();
[Link]();
[Link]();
return 0;
}
5. Hybrid Inheritance
A combination of two or more types of inheritance. Often requires the use of virtual
inheritance to avoid ambiguity.
Example:
#include <iostream>
using namespace std;
// Base class
class A {
public:
void showA() {
cout << "Class A method." << endl;
};
// Intermediate classes
class B : virtual public A {};
class C : virtual public A {};
// Derived class
class D : public B, public C {
public:
void showD() {
cout << "Class D method." << endl;
};
int main() {
D obj;
[Link](); // Access base class method without ambiguity
[Link]();
return 0;
Key Takeaways
Inheritance can follow various models depending on the hierarchy of relationships
between classes.
Multiple inheritance and hybrid inheritance may require careful handling to avoid
ambiguity (using virtual inheritance).
Each inheritance type serves a specific use case in real-world applications.
Assignment
1. Implement a program demonstrating hierarchical inheritance:
Base class: Appliance
Method: showApplianceType() (to display "Appliance").
Derived classes:
WashingMachine (method: washClothes() to display "Washing clothes").
Refrigerator (method: storeFood() to display "Storing food").
Use objects of derived classes to demonstrate functionality.
2. Implement a program demonstrating hybrid inheritance with a scenario of your choice.
Lesson 8: Accessing Inherited Members in C++
How to Access Members of a Base Class in Inheritance?
In C++, access to the members of a base class depends on:
1. The access specifier used during inheritance (public, protected, private).
2. The access specifier of the members in the base class (public, protected, private).
Code Example: Accessing Inherited Members
#include <iostream>
using namespace std;
// Base class
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar;
public:
Base() {
publicVar = 10;
protectedVar = 20;
privateVar = 30;
void showPrivateVar() {
cout << "Private variable: " << privateVar << endl;
};
// Derived class
class Derived : public Base {
public:
void display() {
cout << "Public variable: " << publicVar << endl;
cout << "Protected variable: " << protectedVar << endl;
// privateVar is not accessible directly
cout << "Accessing private variable using base class method: ";
showPrivateVar();
};
int main() {
Derived obj;
[Link]();
// Directly accessing public member of the base class
cout << "Direct access to public variable: " << [Link] << endl;
// Protected and private members cannot be accessed directly
// cout << [Link]; // Error
// cout << [Link]; // Error
return 0;
Explanation
1. Public Members:
Accessible directly through the derived class object (e.g., [Link]).
1. Protected Members:
Accessible within the derived class but not through objects of the derived class.
1. Private Members:
Not directly accessible in the derived class.
Can only be accessed using public or protected methods in the base class.
Key Takeaways
Use public inheritance when you want base class members to retain their access levels
in the derived class.
Use protected inheritance for members to be accessible only within the derived
class hierarchy.
Use private inheritance when you want base class members to be private in the
derived class.
Assignment
1. Implement a program with the following:
Base Class: Employee
Attributes: id (public), name (protected), salary (private).
Method: showSalary() to display salary.
Derived Class: Manager
Method: Access id and name directly and display them. Use showSalary() to
display salary.
1. Test all access levels and verify behavior when inheritance type is:
public
protected
private
Lesson 9: Overriding Member Functions in C++
What Is Function Overriding?
Function overriding occurs when a derived class redefines a member function of the
base class.
The function in the derived class must have the same name, return type, and
parameters as the one in the base class.
It enables runtime polymorphism when used with pointers or references to
base classes.
Key Rules for Function Overriding
1. The base class function must be declared as virtual (optional but recommended).
2. The derived class function must have the same signature (name and parameters) as the
base class function.
3. Use a base class pointer or reference to achieve runtime polymorphism.
Code Example: Function Overriding
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
virtual void draw() { // Virtual function
cout << "Drawing a shape." << endl;
};
// Derived class
class Circle : public Shape {
public:
void draw() override { // Overriding the base class function
cout << "Drawing a circle." << endl;
};
// Another derived class
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing a rectangle." << endl;
};
int main() {
Shape* shapePtr; // Base class pointer
Circle circleObj;
Rectangle rectangleObj;
// Pointing to Circle object
shapePtr = &circleObj;
shapePtr->draw(); // Calls Circle's draw()
// Pointing to Rectangle object
shapePtr = &rectangleObj;
shapePtr->draw(); // Calls Rectangle's draw()
return 0;
}
Explanation
1. Base Class Function:
The draw() function in Shape is declared as virtual, making it overridable.
1. Derived Class Functions:
Both Circle and Rectangle override the draw() function to provide their
specific implementations.
1. Runtime Polymorphism:
Using a Shape* pointer, the draw() function called depends on the object the
pointer points to, enabling dynamic behavior.
When to Use Function Overriding?
When the behavior of a function in a derived class needs to differ from its base
class implementation.
To achieve runtime polymorphism in systems where object types are determined
at runtime.
Key Takeaways
Function overriding works in conjunction with virtual functions in C++.
Use override to explicitly indicate a function is overriding a base class method
(recommended for readability and error-checking).
Base class pointers or references are essential for runtime polymorphism.
Assignment
1. Create the following classes:
Base Class: Animal
Method: makeSound() (virtual, displays "Some generic animal sound").
Derived Classes:
Dog: Overrides makeSound() to display "Woof Woof!"
Cat: Overrides makeSound() to display "Meow!"
2. In the main() function:
Use a base class pointer (Animal*) to point to objects of Dog and Cat.
Call the makeSound() method for each object and observe polymorphic behavior.
Lesson 10: Operator Overloading in C++
What Is Operator Overloading?
Operator overloading allows you to redefine the behavior of an operator for user-
defined data types.
This enhances the readability and functionality of objects while maintaining the natural
syntax of operators.
Key Points to Remember
1. Only existing operators can be overloaded.
2. You cannot create new operators or change their precedence.
3. Some operators like ::, .*, ., and sizeof cannot be overloaded.
4. Overloaded operators must either be member functions or non-member
friend functions.
Syntax for Operator Overloading
1. Member Function:
Syntax: ReturnType operatorSymbol (ArgumentList) { }
Example: Complex operator+(const Complex& c) { }
1. Friend Function:
Syntax: friend ReturnType operatorSymbol (const ClassName& obj1, const
ClassName& obj2) { }
Example: Overloading the + Operator
#include <iostream>
using namespace std;
// Class to represent complex numbers
class Complex {
private:
float real, imag;
public:
Complex(float r = 0, float i = 0) : real(r), imag(i) {}
// Overload + operator as a member function
Complex operator+(const Complex& c) {
return Complex(real + [Link], imag + [Link]);
// Display function
void display() const {
cout << real << " + " << imag << "i" << endl;
};
int main() {
Complex c1(3.5, 2.5), c2(1.5, 3.5);
Complex result = c1 + c2; // Using overloaded + operator
cout << "Result of addition: ";
[Link]();
return 0;
Explanation
1. Operator Declaration:
The operator+ function is declared inside the Complex class.
It takes one parameter (another Complex object) and returns a Complex object.
1. Overloading:
The + operator is redefined to add the real and imaginary parts of two
Complex objects.
1. Usage:
The + operator now works naturally with Complex objects.
Example: Overloading the == Operator as a Friend Function
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// Overload == operator as a friend function
friend bool operator==(const Point& p1, const Point& p2) {
return (p1.x == p2.x) && (p1.y == p2.y);
// Display function
void display() const {
cout << "(" << x << ", " << y << ")" << endl;
};
int main() {
Point p1(3, 4), p2(3, 4), p3(5, 6);
cout << "Comparing p1 and p2: " << (p1 == p2 ? "Equal" : "Not Equal") <<
cout << "Comparing p1 and p3: " << (p1 == p3 ? "Equal" : "Not Equal") <<
return 0;
Key Takeaways
Overloaded operators provide natural syntax for working with objects.
Use member functions when the left operand is the object of the class.
Use friend functions when the left operand isn’t an object of the class or when access
to private data is required.
Assignment
1. Create a Vector class:
Attributes: x, y (integer coordinates).
Overload the + operator to add two vectors.
Overload the * operator to scale a vector by an integer.
2. Create a Matrix class:
Overload the << operator to display the matrix.
Overload the >> operator to input matrix elements.
Lesson 11: Virtual Functions in C++
What Are Virtual Functions?
A virtual function is a member function in a base class that you can override in a
derived class.
Virtual functions support runtime polymorphism, allowing the program to decide
which function to call during execution (based on the type of the object pointed to).
Key Features of Virtual Functions
1. Declared using the virtual keyword in the base class.
2. Enable dynamic dispatch using base class pointers or references.
3. The function in the derived class must have the same name, return type, and parameter
list as the base class.
4. Virtual functions must be invoked through pointers or references to the base class.
Basic Example: Virtual Functions
cppCopyEdit#include <iostream>
using namespace std;
// Base class
class Shape {
public:
virtual void draw() { // Virtual function
cout << "Drawing a shape." << endl;
};
// Derived class
class Circle : public Shape {
public:
void draw() override { // Override the virtual function
cout << "Drawing a circle." << endl;
};
// Another derived class
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing a rectangle." << endl;
}
};
int main() {
Shape* shapePtr; // Base class pointer
Circle circleObj;
Rectangle rectangleObj;
shapePtr = &circleObj;
shapePtr->draw(); // Calls Circle's draw()
shapePtr = &rectangleObj;
shapePtr->draw(); // Calls Rectangle's draw()
return 0;
How It Works
The draw() function is declared as virtual in the base class Shape.
The appropriate draw() function (from Circle or Rectangle) is called at runtime based
on the object the pointer is pointing to.
Advanced Example: Virtual Functions with a Common Interface
cppCopyEdit#include <iostream>
using namespace std;
// Base class
class Animal {
public:
virtual void makeSound() { // Virtual function
cout << "Some generic animal sound." << endl;
};
// Derived class
class Dog : public Animal {
public:
void makeSound() override { // Override the virtual function
cout << "Woof Woof!" << endl;
};
// Another derived class
class Cat : public Animal {
public:
void makeSound() override {
cout << "Meow!" << endl;
};
int main() {
Animal* animalPtr; // Base class pointer
Dog dogObj;
Cat catObj;
animalPtr = &dogObj;
animalPtr->makeSound(); // Calls Dog's makeSound()
animalPtr = &catObj;
animalPtr->makeSound(); // Calls Cat's makeSound()
return 0;
Pure Virtual Functions and Abstract Classes
A pure virtual function is declared by assigning = 0 to a virtual function in the
base class.
A class with at least one pure virtual function becomes an abstract class and cannot
be instantiated.
Example:
cppCopyEdit#include <iostream>
using namespace std;
// Abstract base class
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
// Derived class
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a circle." << endl;
};
int main() {
// Shape shapeObj; // Error: Cannot instantiate an abstract class
Shape* shapePtr;
Circle circleObj;
shapePtr = &circleObj;
shapePtr->draw(); // Calls Circle's draw()
return 0;
Key Takeaways
1. Virtual functions allow for runtime polymorphism.
2. Use base class pointers or references to achieve dynamic dispatch.
3. Pure virtual functions define an interface, making the base class abstract.
Assignment
1. Implement a Vehicle class with a pure virtual function fuelEfficiency().
Derived classes: Car and Truck.
Each derived class provides a unique implementation of fuelEfficiency().
1. Create a base class Appliance with a virtual function powerOn().
Derived classes: WashingMachine and Microwave.
Demonstrate runtime polymorphism using a base class pointer.
Lesson 12: Encapsulation in C++
What Is Encapsulation?
Encapsulation is the process of bundling data (variables) and methods (functions) that
operate on the data into a single unit, typically a class.
It restricts direct access to some components of an object to ensure data security
and integrity.
Key Features of Encapsulation
1. Data Hiding:
The internal state of an object is hidden from the outside world.
Use access specifiers (private, protected, public) to control visibility.
1. Getter and Setter Methods:
Access private data using public methods (getters and setters).
Ensure controlled access and validation.
1. Encapsulation Benefits:
Enhances code modularity.
Protects the data from unintended interference.
Facilitates code maintainability and reuse.
Example: Encapsulation with Getter and Setter
cppCopyEdit#include <iostream>
using namespace std;
class Employee {
private:
string name;
int age;
double salary;
public:
// Setter for name
void setName(const string& employeeName) {
name = employeeName;
// Getter for name
string getName() const {
return name;
// Setter for age
void setAge(int employeeAge) {
if (employeeAge > 0) {
age = employeeAge;
} else {
cout << "Invalid age!" << endl;
// Getter for age
int getAge() const {
return age;
// Setter for salary
void setSalary(double employeeSalary) {
if (employeeSalary >= 0) {
salary = employeeSalary;
} else {
cout << "Invalid salary!" << endl;
// Getter for salary
double getSalary() const {
return salary;
}
// Display Employee details
void display() const {
cout << "Name: " << name << ", Age: " << age << ", Salary: $" << sala
};
int main() {
Employee emp;
[Link]("John Doe");
[Link](30);
[Link](50000.0);
[Link]();
cout << "Accessing details using getters:" << endl;
cout << "Name: " << [Link]() << ", Age: " << [Link]() << ", Sala
return 0;
}
Explanation
1. Private Data Members:
name, age, and salary are private, ensuring they cannot be accessed directly.
1. Public Setters and Getters:
The setName(), setAge(), and setSalary() methods allow controlled updates to the
private data members.
The getName(), getAge(), and getSalary() methods provide read-only access to
private data.
1. Validation:
The setter methods validate inputs (e.g., ensuring age and salary are
non-negative).
Advanced Example: Data Validation in Encapsulation
cppCopyEdit#include <iostream>
using namespace std;
class BankAccount {
private:
string accountHolder;
double balance;
public:
BankAccount(const string& holder, double initialBalance) {
accountHolder = holder;
if (initialBalance >= 0) {
balance = initialBalance;
} else {
balance = 0;
cout << "Invalid initial balance. Setting balance to $0." << endl
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "Deposited $" << amount << ". New balance: $" << balance
} else {
cout << "Invalid deposit amount!" << endl;
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
cout << "Withdrew $" << amount << ". Remaining balance: $" << bal
} else {
cout << "Invalid withdrawal amount or insufficient balance!" << e
double getBalance() const {
return balance;
void display() const {
cout << "Account Holder: " << accountHolder << ", Balance: $" << bala
};
int main() {
BankAccount account("Alice", 1000.0);
[Link]();
[Link](500);
[Link](300);
[Link](2000); // Invalid withdrawal
return 0;
Key Takeaways
1. Encapsulation ensures data security by keeping it private and exposing it only through
controlled methods.
2. Use setters for controlled updates and getters for read-only access.
3. Combine encapsulation with validation to ensure data integrity.
Assignment
1. Create a Student class:
Private attributes: name, rollNumber, marks.
Use setters and getters to assign and retrieve values.
Validate that marks are in the range 0-100.
2. Create a Product class:
Private attributes: productName, price, stock.
Implement methods to:
Set and get details.
Reduce stock on purchase (only if sufficient stock is available).
Lesson 13: Abstraction in C++
What Is Abstraction?
Abstraction is the process of hiding implementation details and showing only the
essential features of an object or system.
In C++, abstraction is achieved using abstract classes and interfaces.
It allows developers to focus on what an object does rather than how it does it.
Key Features of Abstraction
1. Helps reduce complexity by hiding implementation details.
2. Provides a clear separation between the interface and the implementation.
3. Enables the creation of reusable and maintainable code.
Abstraction in C++ Using Abstract Classes
An abstract class is a class that contains at least one pure virtual function. A pure virtual
function is declared by assigning = 0 to a virtual function.
Example: Abstract Class Syntax
cppCopyEditclass AbstractClass {
public:
virtual void pureVirtualFunction() = 0; // Pure virtual function
};
Example: Abstraction with Abstract Classes
cppCopyEdit#include <iostream>
using namespace std;
// Abstract class
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
virtual double area() = 0; // Another pure virtual function
};
// Derived class for Circle
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override {
cout << "Drawing a circle." << endl;
double area() override {
return 3.14 * radius * radius;
};
// Derived class for Rectangle
class Rectangle : public Shape {
private:
double length, width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
void draw() override {
cout << "Drawing a rectangle." << endl;
double area() override {
return length * width;
};
int main() {
Shape* shape; // Base class pointer
Circle circleObj(5.0);
Rectangle rectangleObj(4.0, 6.0);
shape = &circleObj;
shape->draw();
cout << "Circle Area: " << shape->area() << endl;
shape = &rectangleObj;
shape->draw();
cout << "Rectangle Area: " << shape->area() << endl;
return 0;
Explanation
1. Abstract Class:
Shape is an abstract class because it contains pure virtual functions.
1. Derived Classes:
Circle and Rectangle provide specific implementations of the draw() and
area() methods.
1. Dynamic Dispatch:
A base class pointer (Shape*) is used to call derived class methods at runtime.
Advantages of Abstraction
Modularity: Breaks down complex systems into smaller, manageable parts.
Maintainability: Easy to update the implementation without affecting the interface.
Reusability: Abstract classes can serve as blueprints for multiple derived classes.
Abstraction in C++ Using Interfaces
C++ does not have a separate interface keyword, but you can achieve interfaces using abstract
classes where all methods are pure virtual functions.
Example: Interface in C++
cppCopyEdit#include <iostream>
using namespace std;
// Interface
class Printable {
public:
virtual void print() = 0; // Pure virtual function
};
// Class implementing the interface
class Document : public Printable {
public:
void print() override {
cout << "Printing a document." << endl;
};
// Another class implementing the interface
class Image : public Printable {
public:
void print() override {
cout << "Printing an image." << endl;
};
int main() {
Printable* item;
Document doc;
Image img;
item = &doc;
item->print();
item = &img;
item->print();
return 0;
Key Takeaways
1. Abstraction focuses on exposing only the essential features of an object.
2. Abstract classes and interfaces provide a blueprint for derived classes.
3. Use abstraction to design reusable and extensible systems.
Assignment
1. Create an abstract class Vehicle:
Pure virtual functions: start() and stop().
Derived classes: Car and Bike. Implement specific versions of start() and stop()
for each.
1. Design an interface Payment:
Pure virtual function: processPayment().
Implement in CreditCardPayment and PayPalPayment classes.
Lesson 14: File Handling in C++
What Is File Handling?
File handling in C++ enables you to create, read, write, and manipulate files stored on
a disk.
It is an essential feature for data persistence, as it allows programs to store and retrieve
data between executions.
File Streams in C++
C++ provides the fstream library for file handling. The primary classes are:
1. ifstream: Input file stream (used for reading from files).
2. ofstream: Output file stream (used for writing to files).
3. fstream: File stream (used for both reading and writing).
Include Header File:
cppCopyEdit#include <fstream>
Basic File Operations
1. Creating and Writing to a File
2. Reading from a File
3. Appending to a File
4. Checking File Status
Example: Writing to a File
cppCopyEdit#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outFile("[Link]"); // Create and open a file
if (!outFile) {
cout << "Error creating file!" << endl;
return 1;
}
outFile << "Hello, World!" << endl;
outFile << "This is a file handling example in C++." << endl;
cout << "Data written to file successfully." << endl;
[Link](); // Close the file
return 0;
Explanation:
ofstream outFile("[Link]"): Opens the file in write mode. If the file doesn't exist, it
is created.
outFile << "text": Writes data to the file.
[Link](): Closes the file to ensure data is saved.
Example: Reading from a File
cppCopyEdit#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream inFile("[Link]"); // Open the file for reading
if (!inFile) {
cout << "Error opening file!" << endl;
return 1;
string line;
cout << "Reading from the file:" << endl;
while (getline(inFile, line)) { // Read line by line
cout << line << endl;
[Link](); // Close the file
return 0;
Explanation:
ifstream inFile("[Link]"): Opens the file in read mode.
getline(inFile, line): Reads data line by line into a string.
Outputs each line to the console.
Appending to a File
cppCopyEdit#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outFile("[Link]", ios::app); // Open file in append mode
if (!outFile) {
cout << "Error opening file!" << endl;
return 1;
outFile << "Adding more content to the file." << endl;
cout << "Data appended to file successfully." << endl;
[Link](); // Close the file
return 0;
Explanation:
ios::app: Opens the file in append mode. New data is added to the end of the file
without overwriting existing content.
Advanced Example: Reading and Writing Objects to a File
cppCopyEdit#include <iostream>
#include <fstream>
using namespace std;
class Student {
private:
string name;
int rollNumber;
public:
Student() {} // Default constructor
Student(string n, int r) : name(n), rollNumber(r) {}
void display() {
cout << "Name: " << name << ", Roll Number: " << rollNumber << endl;
// Write student data to a file
void saveToFile(ofstream& outFile) {
outFile << name << endl;
outFile << rollNumber << endl;
// Read student data from a file
void loadFromFile(ifstream& inFile) {
getline(inFile, name);
inFile >> rollNumber;
[Link](); // Ignore the newline character after roll number
};
int main() {
Student student1("Alice", 101);
Student student2;
// Writing to a file
ofstream outFile("[Link]");
if (!outFile) {
cout << "Error creating file!" << endl;
return 1;
[Link](outFile);
[Link]();
// Reading from a file
ifstream inFile("[Link]");
if (!inFile) {
cout << "Error opening file!" << endl;
return 1;
[Link](inFile);
[Link]();
cout << "Data loaded from file:" << endl;
[Link]();
return 0;
Explanation:
saveToFile(): Saves the object’s data to a file.
loadFromFile(): Reads data from the file into the object.
Key Takeaways
1. Use ofstream for writing, ifstream for reading, and fstream for both.
2. Always check if the file operation was successful.
3. Close the file after operations to save changes and release resources.
4. Objects can be serialized and deserialized using custom methods.
Assignment
1. Create a Product class with attributes like productID, productName, and price.
Implement methods to:
Save product data to a file.
Load product data from a file.
2. Create a simple text editor:
Provide options to create a file, write to it, append to it, and read its content.
Lesson 15: Exception Handling in C++
What Is Exception Handling?
Exception handling in C++ is used to manage runtime errors, ensuring that the
program can respond to unexpected situations without crashing.
C++ provides try, catch, and throw keywords to handle exceptions.
Key Concepts of Exception Handling
1. Throwing an Exception:
The throw keyword is used to raise an exception.
1. Catching an Exception:
The catch block handles the exception thrown within a try block.
1. Types of Exceptions:
Built-in exceptions (e.g., std::bad_alloc for memory issues, std::out_of_range for
out-of-bounds access).
Custom exceptions (user-defined types).
Basic Syntax of Exception Handling
cppCopyEdittry {
// Code that may throw an exception
throw exception_type; // Throwing an exception
} catch (exception_type& e) {
// Code to handle the exception
// e is the exception object
Example: Handling a Division by Zero Exception
cppCopyEdit#include <iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw runtime_error("Error: Division by zero");
return a / b;
int main() {
int x = 10, y = 0;
try {
int result = divide(x, y);
cout << "Result: " << result << endl;
} catch (const runtime_error& e) {
cout << "Exception caught: " << [Link]() << endl;
return 0;
Explanation
1. Throwing an Exception:
If b == 0, the program throws a runtime_error exception with a custom message.
1. Catching the Exception:
The catch block catches the exception and outputs the error message
using [Link]().
Custom Exceptions
You can define your own exception classes by inheriting from the std::exception class. Here's
an example of creating a custom exception:
cppCopyEdit#include <iostream>
#include <stdexcept>
using namespace std;
class NegativeValueException : public exception {
public:
const char* what() const noexcept override {
return "Error: Negative value not allowed";
};
int calculateSquareRoot(int value) {
if (value < 0) {
throw NegativeValueException(); // Throw custom exception
return sqrt(value);
int main() {
try {
int result = calculateSquareRoot(-25);
cout << "Square root: " << result << endl;
} catch (const NegativeValueException& e) {
cout << "Exception caught: " << [Link]() << endl;
}
return 0;
Explanation:
Custom Exception: NegativeValueException inherits from std::exception and overrides
the what() method.
The exception is thrown when a negative value is passed to calculateSquareRoot().
Multiple Catch Blocks
You can have multiple catch blocks to handle different types of exceptions:
cppCopyEdit#include <iostream>
#include <stdexcept>
using namespace std;
int main() {
try {
int choice;
cout << "Enter 1 for division, 2 for invalid input: ";
cin >> choice;
if (choice == 1) {
int a = 10, b = 0;
if (b == 0) {
throw runtime_error("Error: Division by zero");
}
cout << "Result: " << a / b << endl;
} else if (choice == 2) {
throw invalid_argument("Error: Invalid input");
} else {
throw exception(); // Generic exception
} catch (const runtime_error& e) {
cout << "Runtime error: " << [Link]() << endl;
} catch (const invalid_argument& e) {
cout << "Invalid argument: " << [Link]() << endl;
} catch (const exception& e) {
cout << "Generic error: " << [Link]() << endl;
return 0;
Explanation:
Three catch blocks are used to handle different exception types (runtime_error,
invalid_argument, and a generic exception).
Finally Block (Not Available in C++)
C++ does not have a finally block like some other languages. However, resource management
(such as closing files or releasing memory) can be done using destructors or explicitly after
the try-catch block.
Best Practices for Exception Handling
1. Use Exceptions for Exceptional Situations:
Exceptions should only be used for unexpected events, not for regular flow control.
2. Catch Specific Exceptions First:
Catch more specific exceptions before catching generic ones to handle each
type appropriately.
3. Avoid Catching std::exception Unnecessarily:
Catch only the exceptions you can handle meaningfully.
4. Provide Detailed Exception Information:
Include meaningful messages in the what() method of exceptions to aid debugging.
Key Takeaways
1. Exception Handling in C++ helps manage errors at runtime without crashing
the program.
2. Use throw to raise an exception, try to attempt risky code, and catch to handle errors.
3. You can create custom exceptions by extending the std::exception class.
Assignment
1. Create a BankAccount class:
Throw an exception if an invalid withdrawal amount is attempted (e.g., negative
amount or insufficient balance).
2. Design a Temperature Converter:
Throw an exception if a negative temperature value is passed (for Celsius to
Kelvin conversion).
Share this post:
Recent Posts
Principles of Mobile Computing
21 Jan 2025
Copyright © 2025 Ajinkya Techno Space - All Rights Reserved.
Powered by