Mock Test
Mock Test
Definition:
Function overloading is a feature of polymorphism in C++ that
allows multiple functions to have the same name but with
different parameters (in number, type, or sequence). It
enhances the readability of code and allows programmers to
perform a similar operation in different ways using the same
function name.
In function overloading, the compiler determines which version
of the function to call based on the arguments passed during the
function call. This resolution happens at compile time, which
makes function overloading an example of compile-time
polymorphism.
Key Points:
Functions must differ in:
o Number of parameters
o Type of parameters
o Order of parameters
Return type alone cannot distinguish overloaded functions.
Helps in code reusability and cleaner code.
Example:
int add(int a, int b); // First version
float add(float a, float b); // Second version
int add(int a, int b, int c); // Third version
All these functions have the same name add but different
parameters, hence they are considered overloaded.
Example Program:
#include <iostream>
using namespace std;
class Calculator {
public:
// Function to add two integers
int add(int a, int b) {
return a + b;
}
int main() {
Calculator calc;
return 0;
}
Output:
Addition of 2 and 3: 5
Addition of 2.5 and 3.6: 6.1
Addition of 1, 2 and 3: 6
Concatenation of 'A' and 'B': AB
Limitations:
Overloading cannot be based only on return type.
Complex overloading might reduce code readability if not
used wisely.
Conclusion:
Function overloading in C++ is a powerful tool that allows
developers to write cleaner, more maintainable code by using
the same function name for different types or numbers of
parameters. It is an essential part of object-oriented
programming and compile-time polymorphism.
Definition:
Operator overloading is a feature in C++ that allows predefined
operators (like +, -, *, ==, etc.) to be redefined and used with
user-defined data types (like classes and structures). By
overloading an operator, you can give it a special meaning when
applied to objects of your class, just like it works with basic data
types.
Operator overloading enhances code readability and allows
operators to be used naturally with custom classes, enabling
operator-style syntax for complex operations.
Syntax:
To overload an operator in C++, the keyword operator is used
with the symbol of the operator:
return_type operator<symbol>(arguments)
For example:
Complex operator+(Complex obj); // Overloading the + operator
class Complex {
private:
float real, imag;
public:
// Constructor
Complex(float r = 0, float i = 0) {
real = r;
imag = i;
}
// Overload + operator
Complex operator+(Complex c) {
Complex temp;
temp.real = real + c.real;
temp.imag = imag + c.imag;
return temp;
}
// Overload == operator
bool operator==(Complex c) {
return (real == c.real && imag == c.imag);
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(2.5, 3.5), c2(1.5, 2.5), c3;
return 0;
}
Output:
Sum of complex numbers: 4 + 6i
Complex numbers are not equal.
o . (member access)
o .* (pointer to member)
o sizeof, typeid, ? :, and const_cast, etc.
3. Overloaded operators must have at least one user-
defined type as an operand.
4. You cannot change the operator's precedence or
associativity.
5. You cannot change the number of operands an
operator takes.
6. The meaning of the operation must remain intuitive
and should not mislead the users of your class.
Assignment Operator: =
Increment/Decrement: ++, --
Array Access: []
Benefits:
Makes user-defined types as intuitive as built-in types.
Conclusion:
Operator overloading allows object-oriented style arithmetic and
comparisons, making classes feel like built-in types. However, it
should be used responsibly, keeping the operator's original
meaning intact for better understanding and clarity in code.
Definition:
Polymorphism is a key concept in object-oriented programming
(OOP) that means “many forms.” It allows one interface to be
used for a general class of actions, letting the same function or
operator behave differently in different contexts.
In C++, polymorphism enables objects of different classes to
be treated as objects of a common base class. This is especially
useful for designing flexible and maintainable code.
Types of Polymorphism:
Polymorphism in C++ is mainly classified into two types:
1. Compile-time Polymorphism (Static Polymorphism):
This type is resolved during compilation. It is achieved through:
Function Overloading
Operator Overloading
Virtual Functions
Function Overriding
Compile-time
Run-time Polymorphism
Polymorphism
Happens at compile time Happens at runtime
Function/Operator
Virtual functions
Overloading
Slightly slower due to late
Faster execution
binding
More rigid More flexible and extensible
// Base class
class Animal {
public:
// Virtual function for run-time polymorphism
virtual void sound() {
cout << "Animal makes a sound." << endl;
}
};
// Derived class
class Dog : public Animal {
public:
void sound() override {
cout << "Dog barks." << endl;
}
};
// Derived class
class Cat : public Animal {
public:
void sound() override {
cout << "Cat meows." << endl;
}
};
int main() {
// Compile-time polymorphism
Math m;
cout << "Sum (int): " << m.add(5, 10) << endl;
cout << "Sum (float): " << m.add(3.5f, 2.1f) << endl;
// Run-time polymorphism
Animal* a; // Base class pointer
Dog d;
Cat c;
a = &d;
a->sound(); // Calls Dog's version
a = &c;
a->sound(); // Calls Cat's version
return 0;
}
Output:
Sum (int): 15
Sum (float): 5.6
Dog barks.
Cat meows.
Explanation:
Function Overloading in class Math demonstrates
compile-time polymorphism.
Virtual functions in Animal and sound() overriding in Dog
Advantages of Polymorphism:
Increases flexibility and extensibility.
Conclusion:
Polymorphism allows developers to write generalized and
reusable code. Whether it's compile-time or run-time, it makes
object-oriented systems more flexible and maintainable by
enabling behavior that varies dynamically or based on function
signatures.
Definition:
Polymorphism in C++ refers to the ability of a function,
operator, or object to behave in multiple forms. It is derived
from the Greek words “poly” (many) and “morph” (forms).
Polymorphism allows functions to process objects differently
depending on their data types or classes, improving flexibility
and reusability in code.
There are two major types of polymorphism in C++:
Function Overriding
Virtual Functions
Key Concept:
The base class declares a function as virtual, allowing derived
classes to override it. A base class pointer can call the
overridden method from the derived class during runtime.
// Run-time polymorphism
class Animal {
public:
virtual void makeSound() {
cout << "Some generic animal sound" << endl;
}
};
int main() {
// Compile-time polymorphism
Area a;
cout << "Area of square: " << a.calculate(5) << endl;
cout << "Area of rectangle: " << a.calculate(4, 6) << endl;
// Run-time polymorphism
Animal* pet;
Dog d;
Cat c;
pet = &d;
pet->makeSound(); // Dog's version
pet = &c;
pet->makeSound(); // Cat's version
return 0;
}
Output:
Area of square: 25
Area of rectangle: 24
Dog barks
Cat meows
Benefits of Polymorphism:
Promotes extensibility and scalability
Definition:
File handling in C++ refers to the process of reading from and
writing to files. C++ provides an i/o stream library to perform
file operations. Files allow data to be stored permanently on
disk, even after the program finishes execution. C++ file
handling operations are performed using streams—special
objects that read from or write to a file.
File Operations:
In C++, file handling is done using the following operations:
1. Open: To open a file, use the open() function.
2. Create: A file is created when it is opened in write mode
and doesn't exist.
3. Write: You can write data to a file using the stream
insertion operator (<<).
4. Read: Data is read from a file using the stream extraction
operator (>>).
5. Close: After the file is no longer needed, it is important to
close it using the close() function.
File Modes:
When opening a file, C++ supports various file modes:
ios::in: Open for reading.
int main() {
string text = "Hello, this is a file handling example in C++!";
return 0;
}
Output:
Text written to file successfully.
Text read from file: Hello, this is a file handling example in C++!
Explanation:
1. ofstream outfile("example.txt"): Creates and opens a
file named "example.txt" in write mode. If the file doesn’t
exist, it is created.
2. infile("example.txt"): Opens the same file in read mode.
3. outfile << text: Writes the string text into the file.
4. getline(infile, line): Reads the entire line from the file and
stores it in the line variable.
5. outfile.close() and infile.close(): Closes the files after the
operation is completed.
Definition:
File handling in C++ is the process of opening, reading, writing,
and closing files. It allows us to store data permanently on a
disk. C++ provides built-in classes in the fstream library that
facilitate file operations using streams. The most commonly
used file stream classes are:
ofstream: Used for writing to files.
File Modes:
ios::in: Opens a file for reading.
ios::out: Opens a file for writing.
ios::app: Appends to the end of the file.
ios::ate: Opens a file and moves to the end of the file.
ios::binary: Opens a file in binary mode (instead of text
mode).
int main() {
string data = "This is an example of file handling in C++.";
return 0;
}
Output:
Data written to file successfully.
Data read from file: This is an example of file handling in C++.
Explanation of Steps:
1. Open/Create a File:
o ofstream outFile("sample.txt"); creates and opens the
Important Considerations:
Opening Modes: Depending on the operation (reading,
Conclusion:
File handling in C++ is a crucial aspect of data management,
allowing programs to read and write data to files. By following
the proper steps—opening, creating, writing, reading, and
closing files—developers can manage files efficiently. File
handling also offers great flexibility, as it supports different
modes of operation to suit various use cases.
Definition:
An abstract class in C++ is a class that cannot be instantiated
on its own. It serves as a blueprint for other classes. Abstract
classes allow you to define methods that must be implemented
by derived classes. This helps enforce the structure of derived
classes and ensures they implement necessary functionality. An
abstract class typically includes at least one pure virtual
function.
A pure virtual function is a function that is declared in the
abstract class but has no implementation. It is specified by
assigning 0 to the function in the class declaration.
abstract class.
Contains pure virtual functions: An abstract class must
// Regular function
void display() {
cout << "Displaying the shape." << endl;
}
};
int main() {
// Shape s; // Error: Cannot instantiate abstract class
return 0;
}
Output:
Drawing a circle.
Drawing a rectangle.
Displaying the shape.
Conclusion:
An abstract class is an essential feature in object-oriented
programming that allows you to define common functionality for
derived classes while enforcing that certain functions be
implemented. It plays a critical role in creating extensible,
maintainable, and modular code. Abstract classes are often used
in designing frameworks or libraries where various derived
classes need to share a common interface while having their
own specific implementations.
Definition:
A virtual function in C++ is a function that is declared in the
base class and is meant to be overridden in derived classes. The
primary purpose of a virtual function is to allow runtime
polymorphism (dynamic dispatch), where the method that gets
executed is determined at runtime based on the type of the
object being referred to, rather than the type of the pointer or
reference.
In simple terms, a virtual function ensures that the correct
function (from the derived class) is called, even when using a
base class pointer or reference. This enables us to write code
that works in a more flexible and dynamic way.
// Base class
class Animal {
public:
// Virtual function
virtual void sound() {
cout << "Some generic animal sound!" << endl;
}
};
// Derived class 1
class Dog : public Animal {
public:
// Overriding the virtual function
void sound() override {
cout << "Dog barks!" << endl;
}
};
// Derived class 2
class Cat : public Animal {
public:
// Overriding the virtual function
void sound() override {
cout << "Cat meows!" << endl;
}
};
int main() {
// Base class pointer to derived class objects
Animal* animal;
Dog d;
Cat c;
return 0;
}
Output:
Dog barks!
Cat meows!
Important Considerations:
Virtual Destructor: When a class has virtual functions, it’s
Conclusion:
Virtual functions are crucial in object-oriented programming for
enabling runtime polymorphism and dynamic method dispatch.
By using virtual functions, you can ensure that the correct
function is called based on the actual type of the object, not just
the type of the reference or pointer. This provides more
flexibility and extensibility in your code design, making it easier
to manage and maintain.