Q1. Define operator overloading.
What are the rules for operator
overloading in C++?
Ans.Operator overloading in C++ allows developers to redefine the way operators work for
user-defined types (such as classes). By overloading an operator, you can specify a new
implementation for it when it is used with objects of your class.
For example, you can define how the + operator works for a custom complex number class
to add two complex numbers.
class Complex {
float real, imag;
public:
Complex(float r, float i) : real(r), imag(i) {}
// Overloading the + operator
Complex operator + (const Complex& c) {
return Complex(real + c.real, imag + c.imag);
}
};
Q2.What is the difference between overloading unary and binary
operators in C++?
Ans.
Aspec Unary Operator Overloading Binary Operator Overloading
Number of Operands 1 2
Operator Examples -a, ++a, --a, a + b, a - b, a * b, a
!a == b
Member Function Parameters Takes no Takes 1
arguments argument
Non-Member Function Parameters Takes 1 Takes 2
argument arguments
Syntax (Member) Type Type operator<op>(const
operator<op>() Type&)
Syntax friend Type friend Type
(Non-Member) operator<op>(const operator<op>(const Type&,
Type&) const Type&)
Operand Single operand on right (e.g., Operands on both sides (e.g.,
Position -a) a+b)
Usag b = c = a +
-a; b;
Common Operators +, -, ++, --, +, -, *, /, ==, !=, <, >, =
!, ~ etc.
Q3.What is inheritance? Explain its advantages in OOP.
Ans.Inheritance is a fundamental concept in OOP where a new class (called the derived or
child class) acquires the properties and behaviors (data members and member functions) of
an existing class (called the base or parent class).
This promotes code reuse, extensibility, and helps model real-world relationships.
Advantage Explanation
Code Reusability Avoid rewriting code; reuse base class methods/attributes in
derived classes.
Extensibility Easily extend or enhance base class behavior in derived
classes.
Data Hiding / Protect base class data; expose only necessary details to
Encapsulation derived classes.
Polymorphism Support Enables runtime polymorphism (e.g., virtual functions and
method overriding).
Logical Hierarchy Models real-world relationships (e.g., Vehicle → Car, Bike)
effectively.
Maintainability Centralized changes in base class automatically reflect in all
derived classes.
Q4. What are virtual functions? How do they support runtime
polymorphism?
Ans.Virtual functions are member functions in a base class that you can override in a
derived class. They are declared using the virtual keyword in C++. When you access the
function through a base class pointer or reference, C++ decides at runtime which version
of the function to call (base or derived), depending on the actual object type being pointed
to.
class Base {
public:
virtual void show() {
std::cout << "Base class show()" << std::endl;
}
};
class Derived : public Base {
public:
void show() override {
std::cout << "Derived class show()" << std::endl;
}
};
int main() {
Base* ptr;
Derived d;
ptr = &d;
ptr->show(); // Calls Derived's show() due to virtual function
return 0;
}
Virtual functions enable runtime polymorphism by allowing dynamic dispatch. This
means:
● The function call is resolved at runtime, not at compile-time.
● This is typically achieved using a virtual table (vtable) – a mechanism maintained
by the compiler.
Steps:
1. The base class declares a function as virtual.
2. The derived class overrides the function.
3. When a base class pointer or reference points to a derived class object, and a virtual
function is called:
○ The call is dynamically dispatched to the appropriate version of the function
based on the actual object type.
4. This allows the same interface (base class pointer/reference) to be used for different
behaviors (derived class implementations).
Q5.How do new and delete operators work in C++? Write a
program to demonstrate their usage. new allocates memory
dynamically, and delete deallocates it.
Ans. new operator:
● Allocates memory on the heap.
● Returns a pointer to the allocated memory.
● Automatically calls the constructor (for objects).
delete Operator:
● Deallocates memory previously allocated by new.
● Automatically calls the destructor (for objects).
#include <iostream>
class Student {
public:
std::string name;
int age;
Student(std::string n, int a) {
name = n;
std::cout << "Constructor called for " << name << std::endl;
}
~Student() {
std::cout << "Destructor called for " << name << std::endl;
void display() {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
};
int main() {
// Dynamically allocate a Student object
Student* ptr = new Student("Alice", 20);
// Use the object
ptr->display();
// Deallocate memory
delete ptr;
return 0;
Output:
Constructor called for Alice
Name: Alice, Age: 20
Destructor called for Alice
Q6. Explain class templates and func on templates with suitable
examples.
Ans.In C++, templates allow you to write generic and reusable code. They enable
type-independent programming, meaning you can write a function or class that works with
any data type.
A function template allows you to define a function that can operate on different types
without rewriting the code for each type.
template <typename T>
T add(T a, T b) {
return a + b;
}
A class template allows you to define a class that works with any data type.
template <class T>
class Box {
private:
T value;
public:
void set(T v) { value = v; }
T get() { return value; }
};
Q8. Write a program to overload the << and >> operators for input
and output in a class.
Ans .
#include <iostream>
using namespace std;
class Person {
private:
string name;
int age;
public:
// Friend function to overload >> for input
friend istream& operator>>(istream& in, Person& p);
// Friend function to overload << for output
friend ostream& operator<<(ostream& out, const Person& p);
};
// Overload >> operator (input)
istream& operator>>(istream& in, Person& p) {
cout << "Enter name: ";
getline(in, p.name);
cout << "Enter age: ";
in >> p.age;
in.ignore(); // To clear newline character from input buffer
return in;
}
// Overload << operator (output)
ostream& operator<<(ostream& out, const Person& p) {
out << "Name: " << p.name << ", Age: " << p.age;
return out;
}
int main() {
Person person;
// Use overloaded >> operator
cin >> person;
// Use overloaded << operator
cout << person << endl;
return 0;
}
Output->
Enter name: Alice
Enter age: 25
Name: Alice, Age: 25
Q9. Write a program to overload binary + and unary - operators.
#include <iostream>
using namespace std;
class Number {
private:
int value;
public:
// Constructor
Number(int v = 0) {
value = v;
}
// Overload binary + operator
Number operator+(const Number& obj) {
return Number(value + obj.value);
}
// Overload unary - operator
Number operator-() {
return Number(-value);
}
// Display function
void display() const {
cout << "Value: " << value << endl;
}
};
int main() {
Number num1(10), num2(20);
Number sum = num1 + num2; // Binary +
Number neg = -num1; // Unary -
cout << "num1: "; num1.display();
cout << "num2: "; num2.display();
cout << "Sum: "; sum.display();
cout << "Negation of num1: "; neg.display();
return 0;
}
Q10. Write a program demonstra ng mul level and mul ple
inheritance.
Ans.
#include <iostream>
using namespace std;
// Base class (for multilevel inheritance)
class Person {
public:
void showPerson() {
cout << "This is a Person.\n";
}
};
// Derived class (from Person) – multilevel inheritance
class Employee : public Person {
public:
void showEmployee() {
cout << "This is an Employee (inherits from Person).\n";
}
};
// Another base class (for multiple inheritance)
class Department {
public:
void showDepartment() {
cout << "Belongs to a Department.\n";
}
};
// Derived from Employee and Department – multiple + multilevel
class Manager : public Employee, public Department {
public:
void showManager() {
cout << "This is a Manager (inherits from Employee and Department).\n";
}
};
int main() {
Manager mgr;
// From Person (via Employee - multilevel)
mgr.showPerson();
// From Employee
mgr.showEmployee();
// From Department
mgr.showDepartment();
// From Manager
mgr.showManager();
return 0;
}
Output
This is a Person.
This is an Employee (inherits from Person).
Belongs to a Department.
This is a Manager (inherits from Employee and Department).
Q11.Write a program to demonstrate the basic use of a pure virtual
func on.
Ans.
#include <iostream>
using namespace std;
// Abstract base class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
};
// Derived class must override draw()
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a Circle." << endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing a Rectangle." << endl;
}
};
int main() {
// Shape s; // Error: Cannot instantiate abstract class
Circle c;
Rectangle r;
Shape* shapes[2];
shapes[0] = &c;
shapes[1] = &r;
for (int i = 0; i < 2; i++) {
shapes[i]->draw(); // Calls derived class implementations
}
return 0;
}
Output
Drawing a Circle.
Drawing a Rectangle.
Q12.Write a program to implement a func on template for finding
the maximum of two values.
Ans.#include <iostream>
using namespace std;
// Function template to find maximum of two values
template <typename T>
T findMax(T a, T b) {
return (a > b) ? a : b;
}
int main() {
cout << "Max of 10 and 20: " << findMax(10, 20) << endl;
cout << "Max of 3.5 and 2.7: " << findMax(3.5, 2.7) << endl;
cout << "Max of 'a' and 'z': " << findMax('a', 'z') << endl;
return 0;
}
Output
Max of 10 and 20: 20
Max of 3.5 and 2.7: 3.5
Max of 'a' and 'z': z
Q13.Write a program to demonstrate throwing and catching of
exceptions.
Ans.#include <iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero error!"; // Throwing a C-style string exception
}
return a / b;
}
int main() {
int x = 10;
int y = 0;
try {
int result = divide(x, y); // This will throw an exception
cout << "Result: " << result << endl;
} catch (const char* msg) { // Catching the exception
cout << "Exception caught: " << msg << endl;
}
cout << "Program continues after exception handling." << endl;
return 0;
}
Output
Exception caught: Division by zero error!
Program continues after exception handling.
Q14.. Write a program to demonstrate division by zero using excep
on handling.
Ans.#include <iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero error!"; // Throwing a C-style string exception
}
return a / b
};
int main() {
int x = 10;
int y = 0;
try {
int result = divide(x, y); // This will throw an exception
cout << "Result: " << result << endl;
} catch (const char* msg) { // Catching the exception
cout << "Exception caught: " << msg << endl;
}
cout << "Program continues after exception handling." << endl;
return 0;
}
Q15.Write a program that throws and catches an object of a
user-defined exception on class.
Ans.#include <iostream>
using namespace std;
// User-defined exception class
class MyException {
private:
string message;
public:
MyException(string msg) : message(msg) {}
string what() const { return message; }
};
int main() {
int age;
cout << "Enter your age: ";
cin >> age;
try {
if (age < 0) {
// Throwing object of user-defined exception class
throw MyException("Age cannot be negative!");
}
cout << "Your age is: " << age << endl;
} catch (MyException& e) {
// Catching the exception object
cout << "Exception caught: " << e.what() << endl;
}
cout << "Program continues after exception handling." << endl;
return 0;
}
Output
Enter your age: -5
Exception caught: Age cannot be negative!
Program continues after exception handling.