OOP Answers
OOP Answers
Type Conversions refer to the process of converting a variable from one data type
to another. This is often necessary when performing operations that involve
different data types.
Implicit Type Casting (also known as automatic type conversion) is performed by the
compiler without any explicit instruction from the programmer. This usually happens
when a smaller data type is converted to a larger data type to prevent data loss.
int a = 10;
double b = a; // 'a' is implicitly converted to double
Explicit Type Casting (also known as type casting) is when the programmer
explicitly specifies the type conversion. This is done using casting operators.
double a = 10.5;
int b = (int)a; // 'a' is explicitly converted to int
Example:
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() { // Virtual destructor
cout << "Base destructor called" << endl;
}
};
int main() {
Base* b = new Derived(); // Create a Derived object
delete b; // Delete through base class pointer
return 0;
}
Output:
Example:
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imag;
public:
// Constructor
Complex(float r = 0, float i = 0) : real(r), imag(i) {}
int main() {
Complex c1(3.5, 2.5), c2(1.5, 4.5);
return 0;
}
Output:
5 + 7i
5 + 7i
In this program, the `+` operator is overloaded both as a member function and as a
friend function to add two complex numbers.
2a) Explain Polymorphism and Types of Polymorphism.
class Print {
public:
void show(int i) {
cout << "Integer: " << i << endl;
}
void show(double d) {
cout << "Double: " << d << endl;
}
};
class Base {
public:
virtual void show() {
cout << "Base class show function called." << endl;
}
};
2b) How do you declare and define a pure virtual function in C++? Explain with the
help of a program.
Example:
#include <iostream>
using namespace std;
// Abstract class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0; // No definition in the base class
};
int main() {
Shape* shape1 = new Circle(); // Create a Circle object
Shape* shape2 = new Square(); // Create a Square object
delete shape1;
delete shape2;
return 0;
}
Output:
Drawing a Circle
Drawing a Square
2c) Explain the need for operator overloading. Write a C++ program to demonstrate
the use of unary operator overloading.
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imag;
public:
// Constructor
Complex(float r = 0, float i = 0) : real(r), imag(i) {}
int main() {
Complex c1(1.5, 2.5);
cout << "Original Complex Number: ";
c1.display();
return 0;
}
Output:
In this program, the unary `++` operator is overloaded to increment both the real
and imaginary parts of a complex number. The result is that we can use the `++`
operator intuitively with our `Complex` class.
3a) Explain overloading the extraction (>>) and insertion (<<) operator with the
help of a program.
Overloading the extraction (`>>`) and insertion (`<<`) operators allows us to use
these operators to read from and write to objects of user-defined types, such as
classes. This makes it easier to input and output data in a more intuitive way.
Example:
In this example, we will overload the `>>` operator for input and the `<<` operator
for output for a `Complex` class.
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imag;
public:
// Constructor
Complex(float r = 0, float i = 0) : real(r), imag(i) {}
int main() {
Complex c1;
return 0;
}
Output:
In this program, the `>>` operator is overloaded to read the real and imaginary
parts of a complex number from the user, while the `<<` operator is overloaded to
display the complex number in a user-friendly format.
3b) What are File Pointers? Explain `seekg()` and `tellg()` functions with syntax.
File Pointers are used to keep track of the current position in a file when
performing read or write operations. In C++, file pointers are managed using the
`fstream` library, which provides functions to manipulate the position of the file
pointer.
`seekg()` Function:
- The `seekg()` function is used to set the position of the get pointer (input
pointer) in a file.
- It can be used to move the pointer to a specific location in the file.
Syntax:
file.seekg(offset, direction);
`tellg()` Function:
- The `tellg()` function returns the current position of the get pointer in the
file.
- It is useful for determining where the next read operation will occur.
Syntax:
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Create and open a text file
ofstream outfile("example.txt");
outfile << "Hello, World!" << endl;
outfile << "Welcome to file handling in C++." << endl;
outfile.close();
string line;
while (getline(infile, line)) {
cout << line << endl;
cout << "Current position after reading: " << infile.tellg() << endl;
}
infile.close();
return 0;
}
Output:
Current position: 0
Hello, World!
Current position after reading: 14
Welcome to file handling in C++.
Current position after reading: 45
In this example, we create a file and write some text to it. We then open the file
for reading, use `seekg()` to set the position of the get pointer, and use
`tellg()` to display the current position of the pointer after reading each line.
3c) Write a program that emulates the DOS COPY command. The program should copy
the contents of a text file to another file. Invoke the program with two command-
line arguments—the source file and the destination file. Check that the user has
typed the correct number of command-line arguments and that the specified files can
be opened.
Example Program:
#include <iostream>
#include <fstream>
#include <cstdlib> // For exit()
using namespace std;
cout << "File copied successfully from " << argv[1] << " to " << argv[2] <<
endl;
return 0;
}
File copied successfully from source.txt to destination.txt
This program checks for the correct number of command-line arguments, attempts to
open the specified files, and copies the contents of the source file to the
destination file line by line.
4a) List and explain different mode bits used in the `open()` function while
opening a file. (Any five)
When opening a file in C++, the `open()` function can take various mode bits that
determine how the file will be accessed. Here are five commonly used mode bits:
1. `ios::in`:
- Opens the file for reading.
- If the file does not exist, the open operation fails.
2. `ios::out`:
- Opens the file for writing.
- If the file already exists, its contents are truncated (cleared).
- If the file does not exist, a new file is created.
3. `ios::app`:
- Opens the file for writing, but all output operations are performed at the end
of the file.
- This mode does not truncate the file; it preserves existing content.
4. `ios::binary`:
- Opens the file in binary mode.
- This is used for reading or writing binary files, which allows for non-text
data to be processed correctly.
5. `ios::trunc`:
- If the file is opened for output and it already exists, its contents are
discarded (truncated).
- This mode is often used in conjunction with `ios::out`.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Open a file for writing (truncating if it exists)
ofstream outfile("example.txt", ios::out | ios::trunc);
outfile << "Hello, World!" << endl;
outfile.close();
return 0;
}
In this example, we use `ios::out | ios::trunc` to open a file for writing, which
truncates it if it already exists. We then open the same file for reading using
`ios::in`.
4b) Define a class `Book` that has three attributes: `bookname`, `author`, and
`price`. Write a C++ program that writes an object to a file and reads an object
from a file.
Example Program:
#include <iostream>
#include <fstream>
using namespace std;
class Book {
private:
string bookname;
string author;
float price;
public:
// Constructor
Book(string bname = "", string auth = "", float pr = 0.0)
: bookname(bname), author(auth), price(pr) {}
int main() {
// Create a Book object
Book book1("The Great Gatsby", "F. Scott Fitzgerald", 10.99);
return 0;
}
Output:
In this program, we define a `Book` class with attributes for the book name,
author, and price. We implement methods to write the book details to a file and
read them back from a file. The program demonstrates writing a `Book` object to a
file and then reading it back to display the details.
4c) What do you mean by file handling? Explain the following functions with syntax
and an example:
i) `open()`
ii) `read()`
iii) `write()`
File Handling in C++ refers to the process of creating, opening, reading, writing,
and closing files. It allows programs to store data permanently and retrieve it
later. C++ provides the `fstream` library to handle file operations.
# i) `open()`
The `open()` function is used to open a file. It can take a filename and a mode
(like read, write, etc.) as arguments.
Syntax:
fstream file;
file.open("filename.txt", ios::in | ios::out | ios::app);
# ii) `read()`
The `read()` function is used to read data from a file. It can read a specified
number of bytes from the file into a buffer.
Syntax:
file.read(buffer, size);
# iii) `write()`
The `write()` function is used to write data to a file. It writes a specified
number of bytes from a buffer to the file.
Syntax:
file.write(buffer, size);
Example Program:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Writing to a file
ofstream outFile;
outFile.open("example.txt", ios::out); // Open file for writing
if (!outFile) {
cerr << "Error opening file for writing!" << endl;
return 1;
}
string data = "Hello, World!";
outFile.write(data.c_str(), data.size()); // Write data to file
outFile.close(); // Close the file
return 0;
}
Output:
Exceptions in C++ are a way to handle errors or exceptional conditions that occur
during the execution of a program. The main goal of exception handling is to
separate error-handling code from regular code, making the program easier to read
and maintain.
Example:
#include <iostream>
using namespace std;
int main() {
try {
divide(10, 0); // This will throw an exception
} catch (const runtime_error& e) {
cout << "Caught an exception: " << e.what() << endl; // Catching the
exception
}
return 0;
}
Output:
In this example, the `divide` function checks if the denominator is zero. If it is,
it throws a `runtime_error` exception. In the `main` function, we use a `try` block
to call `divide`, and if an exception is thrown, it is caught in the `catch` block,
where we print the error message.
Class Templates in C++ allow us to create a blueprint for a class that can work
with any data type. This enables code reusability and type safety, as we can define
a class once and use it with different data types without rewriting the code.
Syntax:
template <typename T>
class ClassName {
// Class definition using type T
};
Example:
In this example, we will create a simple class template for a `Pair` that holds two
values of the same type.
#include <iostream>
using namespace std;
public:
// Constructor
Pair(T f, T s) : first(f), second(s) {}
int main() {
// Create a Pair of integers
Pair<int> intPair(10, 20);
intPair.display();
cout << "Sum: " << intPair.sum() << endl;
return 0;
}
Output:
In this example, we define a class template `Pair` that can hold two values of the
same type `T`. We create instances of `Pair` for both `int` and `double` types,
demonstrating how the same class template can be used with different data types.
The `display` function shows the values, and the `sum` function calculates the sum
of the two values.
In this example, we will create a simple program that performs division and
demonstrates how to handle a "divide by zero" exception using C++ exception
handling.
Example Program:
#include <iostream>
#include <stdexcept> // For std::runtime_error
using namespace std;
int main() {
double num, denom;
try {
double result = divide(num, denom); // Attempt to divide
cout << "Result: " << result << endl;
} catch (const runtime_error& e) {
cout << e.what() << endl; // Catching and displaying the exception message
}
return 0;
}
Output:
Enter numerator: 10
Enter denominator: 0
Error: Division by zero!
In this program, the `divide` function checks if the denominator is zero. If it is,
it throws a `runtime_error` exception. In the `main` function, we prompt the user
for input and attempt to perform the division. If a division by zero occurs, the
exception is caught, and an appropriate error message is displayed.
#include <iostream>
#include <string>
using namespace std;
int main() {
double num, denom;
try {
double result = divide(num, denom); // Attempt to divide
cout << "Result: " << result << endl;
} catch (const DivisionByZeroException& e) {
cout << e.what() << endl; // Catching and displaying the user-defined
exception message
}
return 0;
}
Output:
Enter numerator: 10
Enter denominator: 0
Error: Division by zero!
6b) What is a template in C++? Discuss templates with multitype parameters in C++.
Templates in C++ are a powerful feature that allows developers to create generic
classes and functions. This means that you can write a function or class that can
operate with any data type without needing to rewrite the code for each type.
Templates enable code reusability and type safety.
1. Function Templates: Allow you to create a function that can work with any data
type.
2. Class Templates: Allow you to create a class that can work with any data type.
Multitype Parameters in Templates: C++ also supports templates with multiple type
parameters, allowing you to define functions or classes that can accept more than
one type.
#include <iostream>
using namespace std;
public:
// Constructor
Pair(T1 f, T2 s) : first(f), second(s) {}
int main() {
// Create a Pair of int and double
Pair<int, double> intDoublePair(10, 20.5);
intDoublePair.display();
return 0;
}
Output:
In this example, we define a class template `Pair` that takes two type parameters,
`T1` and `T2`. This allows us to create pairs of different types, such as an `int`
and a `double`, or a `string` and a `char`. The `display` function shows the values
of the pair.
6c) Write a program to demonstrate function templates in C++.
Function templates allow you to create a single function definition that can work
with different data types. This is useful for writing generic functions that can
operate on various types without code duplication.
Example Program:
In this example, we will create a function template to find the maximum of two
values.
#include <iostream>
using namespace std;
int main() {
// Using the function template with int
int int1 = 10, int2 = 20;
cout << "Max of " << int1 << " and " << int2 << " is: " << findMax(int1, int2)
<< endl;
return 0;
}
Output:
In this program, we define a function template `findMax` that takes two parameters
of the same type and returns the maximum of the two. We demonstrate the use of this
function template with different data types: `int`, `double`, and `char`. The same
function works seamlessly with all these types, showcasing the power of function
templates in C++.
In C++, a `map` is a part of the Standard Template Library (STL) and is used to
store key-value pairs. It is an associative container that allows fast retrieval of
values based on their keys. The keys in a map are unique, and the map is usually
implemented as a balanced binary tree.
Example Program:
In this example, we will create a map to store the names of students and their
corresponding scores.
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
// Create a map to store student names and their scores
map<string, int> studentScores;
return 0;
}
Output:
Student Scores:
Alice: 85
Bob: 90
Charlie: 78
Bob's score: 90
David is not in the map.
The Standard Template Library (STL) in C++ provides several types of containers to
store collections of data. Here are some of the commonly used containers:
1. Vector: A dynamic array that can grow in size. It allows random access to
elements.
2. List: A doubly linked list that allows efficient insertion and deletion of
elements.
3. Deque: A double-ended queue that allows insertion and deletion at both ends.
4. Set: A collection of unique elements, implemented as a balanced binary tree.
5. Map: A collection of key-value pairs, where keys are unique.
6. Multiset: Similar to a set, but allows duplicate elements.
7. Multimap: Similar to a map, but allows duplicate keys.
Example Program:
#include <iostream>
#include <vector>
using namespace std;
int main() {
// Create a vector of integers
vector<int> numbers;
return 0;
}
Output:
STL (Standard Template Library) is a powerful set of C++ template classes and
functions that provide general-purpose classes and functions for data structures
and algorithms. It is designed to provide a standard way to manage collections of
data and perform operations on them efficiently.
1. Containers: These are data structures that store objects and data. They can be
classified into:
- Sequence Containers: Store elements in a linear order (e.g., `vector`, `list`,
`deque`).
- Associative Containers: Store elements in a way that allows for fast retrieval
based on keys (e.g., `set`, `map`, `multiset`, `multimap`).
- Unordered Associative Containers: Store elements in a hash table for faster
access (e.g., `unordered_set`, `unordered_map`).
3. Iterators: Iterators are objects that allow you to traverse the elements of a
container. They provide a way to access the elements of a container without
exposing the underlying structure. Iterators can be thought of as generalized
pointers. Types of iterators include:
- Input Iterators: Read elements from a container.
- Output Iterators: Write elements to a container.
- Forward Iterators: Can read and write elements in a single pass.
- Bidirectional Iterators: Can move both forward and backward.
- Random Access Iterators: Can access elements at arbitrary positions.
4. Function Objects (Functors): These are objects that can be called as if they
were functions. They are often used with algorithms to provide custom behavior.
5. Allocators: Allocators are used to manage memory for containers. They define how
memory is allocated and deallocated for the elements stored in the containers.
#include <iostream>
#include <vector>
#include <algorithm> // For sort
using namespace std;
int main() {
// Create a vector of integers
vector<int> numbers = {5, 2, 8, 1, 4};
return 0;
}
Output:
Sorted numbers: 1 2 4 5 8
In this example, we create a vector of integers, sort it using the `sort` algorithm
from STL, and then display the sorted numbers using an iterator. This showcases how
STL components work together to provide efficient data management and manipulation.
Types of Iterators:
1. Input Iterator:
- Allows reading elements from a container.
- Can be used to read each element only once.
- Supports operations like `++` (increment) and `*` (dereference).
2. Output Iterator:
- Allows writing elements to a container.
- Can be used to write each element only once.
- Supports operations like `++` (increment) and `*` (dereference).
3. Forward Iterator:
- Can read and write elements in a single pass.
- Supports incrementing and dereferencing.
- Can be used to traverse a container in one direction (forward).
4. Bidirectional Iterator:
- Can read and write elements and can move both forward and backward.
- Supports incrementing (`++`) and decrementing (`--`) operations.
#include <iostream>
#include <vector>
using namespace std;
int main() {
// Create a vector of integers
vector<int> numbers = {10, 20, 30, 40, 50};
return 0;
}
Output:
1. `insert()`:
- Inserts a new key-value pair into the map.
- If the key already exists, the insertion is ignored.
- Syntax: `map.insert(make_pair(key, value));` or `map[key] = value;`
2. `find()`:
- Searches for a key in the map and returns an iterator to the element if found.
- If the key is not found, it returns an iterator to the end of the map.
- Syntax: `map.find(key);`
3. `erase()`:
- Removes an element from the map based on the key.
- Syntax: `map.erase(key);`
4. `size()`:
- Returns the number of elements in the map.
- Syntax: `map.size();`
5. `clear()`:
- Removes all elements from the map.
- Syntax: `map.clear();`
6. `operator[]`:
- Accesses the value associated with a given key. If the key does not exist, it
inserts a new element with the default value.
- Syntax: `map[key];`
#include <iostream>
#include <map>
using namespace std;
int main() {
// Create a map to store student names and their scores
map<string, int> studentScores;
// Erasing an element
studentScores.erase("Alice");
cout << "After removing Alice:" << endl;
for (const auto& pair : studentScores) {
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}
Output:
Student Scores:
Alice: 85
Bob: 90
Charlie: 78
Bob's score: 90
After removing Alice:
Bob: 90
Charlie: 78
Total students: 2
Total students after clearing: 0
In this example, we create a map to store student names and their scores. We
demonstrate various functions such as inserting elements, finding a specific key,
erasing an element, checking the size of the map, and clearing the map. This
showcases the functionality and utility of maps in C++.
#include <iostream>
#include <vector>
using namespace std;
int main() {
// Create a vector of integers
vector<int> numbers;
return 0;
}
Output: