0% found this document useful (0 votes)
15 views54 pages

Model Answer Paper Solution

The document is a model answer paper for a supplementary summer exam in Object-Oriented Programming (OOP) using C++. It covers key concepts such as characteristics of OOP, constructors, inheritance, polymorphism, and abstract classes, providing definitions, examples, and comparisons between OOP and procedural programming. The document also includes code snippets to illustrate various OOP principles and features.

Uploaded by

cadici8457
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views54 pages

Model Answer Paper Solution

The document is a model answer paper for a supplementary summer exam in Object-Oriented Programming (OOP) using C++. It covers key concepts such as characteristics of OOP, constructors, inheritance, polymorphism, and abstract classes, providing definitions, examples, and comparisons between OOP and procedural programming. The document also includes code snippets to illustrate various OOP principles and features.

Uploaded by

cadici8457
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 54

Model Answer Paper Solution

(Supplementary Summer Exam-2024)

Sub Name:-OOP in CPP Dept: - CSE


Sub Code:-BTCOC305 Sem: - III

Q.1 Solve any two of the following.


a) Describe characteristic of object oriented programming.

Ans:- Object-oriented programming (OOP) is a programming paradigm based on the concept


of "objects," which can contain data and code. Here are some key characteristics:

1. Encapsulation: Bundling data and methods that operate on the data within one unit, or
class. This hides the internal state and requires all interaction to occur through well-
defined interfaces. This principle protects the object's internal state from unintended
interference and misuse by restricting direct access to some of its components. Access is
controlled through methods, which can enforce rules or constraints
2. Abstraction: Simplifying complex reality by modeling classes based on the essential
properties and behaviors an object should have, while ignoring the irrelevant details.By
exposing only the relevant properties and behaviors of an object, abstraction helps to
reduce complexity and increase efficiency. It allows developers to focus on high-level
functionalities without needing to understand every detail of the implementation.
3. Inheritance: Allowing a new class to inherit properties and methods from an existing
class, promoting code reuse and establishing a hierarchical relationship between
classes.This feature enables a new class (subclass) to inherit attributes and methods from
an existing class (superclass), fostering code reuse and creating a natural hierarchy. It
allows for the creation of more specific classes based on general ones.
4. Polymorphism: Enabling a single interface to represent different underlying forms (data
types). It allows methods to do different things based on the object it is acting upon, often
achieved through method overriding and overloading. This characteristic allows different
classes to be treated as instances of the same class through a common interface. It
enhances flexibility in code and can simplify the implementation of complex systems by
allowing one interface to be used for different data types.
5. Composition: Building complex objects by combining simpler objects, allowing for
greater flexibility and modular design. Unlike inheritance, which creates an "is-a"
relationship, composition creates a "has-a" relationship. It allows for building complex
types by combining simpler, reusable components, enhancing modularity and
maintainability.
6. Dynamic memory management: in C++ allows you to allocate and deallocate memory
at runtime. This is crucial for creating flexible and efficient programs that can handle
varying data sizes. Here’s an overview of key concepts and techniques related to dynamic
memory management in C++:

Key Concepts

7. Dynamic Memory Allocation:


1. Use new to allocate memory on the heap.
2. Use delete to deallocate memory.

b) Explain Constructor in OOP using suitable example.

Ans:- In object-oriented programming (OOP) in C++, a constructor is a special member function


that is automatically called when an object of a class is created. Its main purpose is to initialize
the object's data members. Constructors have the same name as the class and do not have a return
type.

Key Features of Constructors

1. Automatic Invocation: Constructors are called automatically when an object is created.


2. No Return Type: Constructors do not return values, not even void.
3. Overloading: You can have multiple constructors in a class (constructor overloading) to
allow different ways of initializing objects.

Types of Constructors

1. Default Constructor: A constructor that takes no arguments or has default values for its
parameters.
2. Parameterized Constructor: A constructor that takes parameters to initialize an object
with specific values.
3. Copy Constructor: A constructor that creates a new object as a copy of an existing
object.

Example:-

#include <iostream>

#include <string>

class Person {

private:
std::string name;

int age;

public:

// Default constructor

Person() {

name = "Unknown";

age = 0;

// Parameterized constructor

Person(std::string n, int a) {

name = n;

age = a;

// Method to display information

void display() {

std::cout << "Name: " << name << ", Age: " << age << std::endl;

};

int main() {
// Creating an object using the default constructor

Person person1;

person1.display(); // Output: Name: Unknown, Age: 0

// Creating an object using the parameterized constructor

Person person2("Alice", 30);

person2.display(); //

return 0;

Output: Name: Alice, Age: 30

C) Differentiate between OOP and Procedural Programming.

POP OOP
C was developed by Dennis Ritchie C++ was developed by Bjarne
between the year 1969 and 1973 at Stroustrup in 1979.
AT&T Bell Labs.
C is (mostly) a subset of C++ C is (mostly) a subset of C++
C does not support information Data is hidden by the Encapsulation
hiding. to ensure that data structures and
operators are used as intended.
Built-in data types is supported in C. Built-in & user-defined data types is
supported in C++.
Function and operator overloading is Function and operator overloading is
not supported in C. supported by C++.
Standard IO header is stdio.h. Standard IO header is iostream.h.
C does not support inheritance. C++ supports inheritance.
C structures don’t have access C ++ structures have access
modifiers. modifiers.
File extension is “.c” File extension is “.cpp” or “.c++” or
“.cc” or “.cxx”
There are 32 keywords in the C There are 97 keywords in the C++
Q.2 Solve any Two of the Following.

a) Differentiate between base class and derived class.


Base Class Derived Class
A base class is an existing class from which the A derived class is a class that is constructed from a
other classes are derived and inherit the methods base class or an existing class.
and properties.
Base class can’t acquire the methods and Derived class can acquire the methods and
properties of the derived class. properties of the base class.
The base class is also called superclass or parent The derived class is also called a subclass or child
class. class.

Syntax: Syntax:
class BaseClass{ class DerivedClass : access_specifier
// members…. BaseClass{
// member function // members….
} // member function
}

b) Define Multiple Inheritance and its advantages.

Ans:- Multiple Inheritance is a feature in C++ (and some other object-oriented programming
languages) that allows a class to inherit from more than one base class. This means that a derived class
can acquire attributes and methods from multiple parent classes.

Advantages of Multiple Inheritance:

1. Reusability: Multiple inheritance allows you to reuse code from different classes,
promoting code reuse and reducing redundancy.
2. Complex Relationships: It enables the modeling of complex relationships where an
object may logically belong to multiple categories. For instance, a class FlyingCar could
inherit from both Car and Aircraft.
3. Flexibility: Developers have the flexibility to combine features from multiple classes,
which can be useful in scenarios requiring rich functionality.
4. Interface Implementation: Multiple inheritance can be used to implement interfaces
from different sources, allowing a derived class to define behaviors from several base
classes.
5. Enhanced Functionality: A derived class can extend or modify the behavior of multiple
base classes, providing enhanced functionality without rewriting code.

Example:

Here's a simple example to illustrate multiple inheritance:


#include <iostream>

#include <string>

// Base class 1

class Writer {

public:

void write() {

std::cout << "Writing content..." << std::endl;

};

// Base class 2

class Artist {

public:

void draw() {

std::cout << "Drawing art..." << std::endl;

};

// Derived class inheriting from both Writer and Artist

class CreativePerson : public Writer, public Artist {

public:

void express() {
std::cout << "Expressing creativity!" << std::endl;

};

int main() {

CreativePerson person;

person.write();

person.draw();

person.express();

return 0;

Output: Writing content...

Output: Drawing art...

Output: Expressing creativity!

c) Define Inheritance and explain any two types with suitable example.

Ans:- Inheritance is a fundamental concept in object-oriented programming that allows a class


(known as a derived or child class) to inherit attributes and behaviors (methods) from another
class (known as a base or parent class). This promotes code reuse and establishes a natural
hierarchy between classes.

Types of Inheritance

1. Single Inheritance
2. Multiple Inheritance

1. Single Inheritance

In single inheritance, a derived class inherits from only one base class. This is the simplest
form of inheritance.
Example:

#include <iostream>

#include <string>

// Base class

class Animal {

public:

void speak() {

std::cout << "Animal speaks!" << std::endl;

};

// Derived class

class Dog : public Animal {

public:

void bark() {

std::cout << "Dog barks!" << std::endl;

};

int main() {

Dog dog;

dog.speak(); // Inherited method from Animal


dog.bark(); // Method from Dog

return 0;

Output:

Animal speaks!

Dog barks!

Explanation:

 Base Class: Animal has a method speak().


 Derived Class: Dog inherits from Animal and has its own method bark().
 In main, we create a Dog object and call both inherited and its own methods.

2. Multiple Inheritance

In multiple inheritance, a derived class inherits from more than one base class. This allows
for more complex relationships.

Example:

#include <iostream>

#include <string>

// Base class 1

class Writer {

public:

void write() {

std::cout << "Writing content..." << std::endl;

}
};

// Base class 2

class Artist {

public:

void draw() {

std::cout << "Drawing art..." << std::endl;

};

// Derived class inheriting from both Writer and Artist

class CreativePerson : public Writer, public Artist {

public:

void express() {

std::cout << "Expressing creativity!" << std::endl;

};

int main() {

CreativePerson person;

person.write(); //

person.draw();

person.express();
return 0;

Output: Writing content...

Output: Drawing art…

Output: Expressing creativity!

Q.3 Solve Any two of the following.

a) Define abstract classes and their purpose in object-oriented


programming.

Ans:- An abstract class in object-oriented programming is a class that cannot be instantiated


directly and is designed to be a base class for other classes. It typically contains one or more pure
virtual functions—functions declared in the class but without an implementation. Abstract classes
serve as blueprints for derived classes, ensuring that certain methods are implemented in those
derived classes.

Purpose of Abstract Classes:

1. Establishing Interfaces: Abstract classes define a common interface for all derived
classes. They ensure that derived classes implement specific methods, promoting
consistency.
2. Encapsulation of Shared Behavior: They can contain common data members and
methods that can be shared across derived classes, reducing code duplication.
3. Facilitating Polymorphism: Abstract classes allow for polymorphism, enabling you to
use a base class reference to refer to derived class objects. This is particularly useful in
scenarios where the exact type of the object may not be known at compile time.
4. Designing Frameworks: They are often used in frameworks where certain methods must
be defined by the user of the framework while providing default implementations for
other methods.

Example:

#include <iostream>

// Abstract class

class Shape {

public:
// Pure virtual function

virtual void draw() = 0;

// Regular method

void info() {

std::cout << "This is a shape." << std::endl;

};

// Derived class 1

class Circle : public Shape {

public:

void draw() override {

std::cout << "Drawing a Circle." << std::endl;

};

// Derived class 2

class Square : public Shape {

public:

void draw() override {

std::cout << "Drawing a Square." << std::endl;

};
int main() {

// Shape shape; // Error: Cannot instantiate an abstract class

Circle circle;

Square square;

// Using base class reference to call derived class methods

Shape* shape1 = &circle;

Shape* shape2 = &square;

shape1->info();

shape1->draw();

shape2->info();

shape2->draw();

return 0;

Output: This is a shape.

Output: Drawing a Circle.

Output: This is a shape.

Output: Drawing a Square.


b) Define ‘this’ operator explain its syntax with suitable example.
The this operator in C++ is a special pointer available within non-static member functions of a
class. It points to the object for which the member function is called. The this pointer allows access
to the calling object's members and is especially useful in situations where member names are
shadowed by parameters or other local variables.

Syntax

The syntax for using this is straightforward. Within a member function, you can use this to
refer to the object:

this->member_variable

Example

Here’s an example to illustrate the usage of the this operator:

#include <iostream>

#include <string>

class Box {

private:

double length;

double width;

public:

// Constructor

Box(double length, double width) {

// Using 'this' to differentiate between member variables and parameters

this->length = length;

this->width = width;
}

// Method to calculate area

double area() {

return this->length * this->width; // 'this' is optional here

// Method to display dimensions

void display() {

std::cout << "Length: " << this->length << ", Width: " << this->width << std::endl; // 'this'
is optional here

};

int main() {

Box box1(3.5, 2.0);

box1.display();

std::cout << "Area: " << box1.area() << std::endl;

return 0;

Output: Length: 3.5, Width: 2.0

Output: Area: 7.0


Explanation

1. Class Definition: We define a class Box with private member variables length and
width.
2. Constructor: The constructor takes two parameters with the same names as the member
variables. The this pointer is used to distinguish the member variables from the
parameters:

this->length = length;
this->width = width;

3. Methods:
o The area() method calculates the area of the box. Although this is not strictly
necessary here, it can be used for clarity.
o The display() method prints the dimensions of the box. Again, this is optional
but clarifies that we are accessing member variables.
4. Main Function: An instance of Box is created, and its methods are called to display the
dimensions and area.

The this operator is an essential part of C++ that enhances code clarity, especially when
dealing with member variable shadowing. It allows you to explicitly refer to the calling object's
members, making your code more understandable and maintainable.

c) Describe the concept of Polymorphism with suitable example.


Ans:-

Polymorphism is a fundamental concept in object-oriented programming that allows objects of


different classes to be treated as objects of a common base class. The term means "many
shapes" and refers to the ability of different classes to provide a unique implementation of the
same interface or function. Polymorphism is primarily achieved through method overriding and
method overloading.

Types of Polymorphism

1. Compile-Time Polymorphism (also known as static polymorphism):


o Achieved through function overloading and operator overloading.
o Resolved at compile time.
2. Run-Time Polymorphism (also known as dynamic polymorphism):
o Achieved through method overriding using virtual functions.
o Resolved at runtime.

Example of Run-Time Polymorphism


example that demonstrates run-time polymorphism using a base class and derived classes:

#include <iostream>

using namespace std;

// Base class

class Shape {

public:

// Virtual function for drawing

virtual void draw() {

cout << "Drawing a Shape." << endl;

};

// Derived class 1

class Circle : public Shape {

public:

void draw() override { // Overriding the draw function

cout << "Drawing a Circle." << endl;

};

// Derived class 2

class Square : public Shape {


public:

void draw() override { // Overriding the draw function

cout << "Drawing a Square." << endl;

};

void renderShape(Shape* shape) {

shape->draw(); // Calls the appropriate draw() method based on the object type

int main() {

Shape* shape1 = new Circle();

Shape* shape2 = new Square();

renderShape(shape1); renderShape(shape2);

// Clean up

delete shape1;

delete shape2;

return 0;

Output: Drawing a Circle.

Output: Drawing a Square.

Explanation:
1. Base Class: The Shape class has a virtual function draw(). This indicates that derived
classes can override this method to provide their own implementation.

2. Derived Classes:
o Circle and Square inherit from Shape and override the draw() method to
provide specific implementations.
3. Function to Render Shape: The renderShape() function takes a pointer to the base
class Shape. Inside this function, when shape->draw() is called, it invokes the
overridden method of the actual object type (either Circle or Square).
4. Main Function:
o In the main() function, we create objects of Circle and Square but treat them as
Shape pointers (upcasting).
o When renderShape() is called with these pointers, the appropriate draw()
method is executed based on the actual object type, demonstrating run-time
polymorphism.

Polymorphism is a powerful feature of object-oriented programming that enhances flexibility


and reusability. It allows for writing more generic and extensible code, enabling functions and
methods to work with different types of objects while relying on a common interface. This leads
to cleaner and more maintainable code.

Q4. Solve Stream input and output with suitable Example.

1. Describe Stream input and output with suitable example.

Ans- In programming, stream input and output (I/O) refer to the process of reading data from
and writing data to different sources (such as the keyboard, files, or network resources) in a
sequential manner. This is typically handled through streams, which can be categorized as input
streams (for reading data) and output streams (for writing data).

stream input and output (I/O) in C++. Stream I/O is a method for handling data that allows a
program to read from and write to various sources, such as files, in a continuous flow or stream.
It helps manage resources efficiently, particularly when dealing with large amounts of data.

Input Stream in C++

An input stream is used to read data from a source. Common examples are:

 Reading from the keyboard (console input).


 Reading from a file.
 Reading from a file (Stream Input):
 In this example, std::ofstream outputFile("output.txt"); opens the file
output.txt in write mode. The << operator is used to write data to the file. Data is
written to the file in a continuous stream, and the close() method ensures the file is
properly closed after writing.
 Stream I/O in C++ is especially useful for efficiently handling large amounts of data,
network communications, and other scenarios where managing resources and processing
data in a continuous flow is crucial.

C++ provides the istream class to handle input, with common objects like cin (for reading from
the keyboard) and ifstream (for reading from files).

#include <iostream>

#include <string>

using namespace std;

int main() {

string name;

// Reading input from the user (keyboard)

cout << "Enter your name: ";

cin >> name; // Reading a string from the console

cout << "Hello, " << name << "!" << endl;

return 0;

Example of Input Stream (File Input)

The following C++ program reads data from a file using ifstream:
Example of Input Stream (File Input)

The following C++ program reads data from a file using ifstream:

Example: File Reading and Writing in C++

Here's a simple example of how to use stream input and output in C++ to read from a file and
write to another file.

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

int main() {

ifstream inputFile("sample.txt"); // Open the file "sample.txt"

string line;

// Check if the file opened successfully

if (!inputFile) {

cout << "Error opening the file." << endl;

return 1;

// Reading data from the file line by line


while (getline(inputFile, line)) {

cout << line << endl; // Print each line to the console

inputFile.close(); // Close the file

return 0;

n this example:

 ifstream is used to open and read data from a file (sample.txt).


 The program reads the content of the file line by line using getline().

2. Output Stream in C++

An output stream is used to send data to a destination. Common examples are:

 Writing to the console (standard output).


 Writing to a file.

C++ provides the ostream class to handle output, with common objects like cout (for writing to
the console) and ofstream (for writing to files).

xample of Output Stream (Console Output)

The following C++ program demonstrates writing data to the console using cout:

#include <iostream>

using namespace std;

int main() {

string message = "Hello, World!";


// Writing data to the console (standard output)

cout << message << endl;

return 0;

In this example:

 cout is used to send output to the console (standard output).


 The program writes the string "Hello, World!" to the console.

Example of Output Stream (File Output)

The following C++ program writes data to a file using ofstream:

#include <iostream>

#include <fstream>

using namespace std;

int main() {

ofstream outputFile("output.txt"); // Open a file for writing

// Check if the file is opened successfully

if (!outputFile) {

cout << "Error opening the file for writing." << endl;

return 1;

}
// Writing data to the file

outputFile << "This is a sample text written to the file." << endl;

outputFile.close(); // Close the file

cout << "Data written to the file successfully." << endl;

return 0;

In this example:

 ofstream is used to open a file (output.txt) for writing.


 The program writes a string to the file.
 Input Streams in C++:
o cin for reading from the console.
o ifstream for reading from a file.
 Output Streams in C++:
o cout for writing to the console.
o ofstream for writing to a file.

Streams allow data to flow sequentially, which is essential for processing input and output in
programs, especially when dealing with large volumes of data or files.

2. Write short note on Stream Manipulators

Ans- Stream manipulators are used in C++ to control the formatting and input/output operations of
streams. They allow for more precise control over how data is displayed or read, making it easier to
format output and parse input. These manipulators are typically used with the insertion ( <<) and
extraction (>>) operators.

stream manipulators in C++ are special functions used to modify the behavior of input and output
operations, specifically with streams such as cin, cout, ifstream, and ofstream. These manipulators
can be used to format the output or control the input/output behavior in a more flexible way.

Manipulators are defined in the <iomanip> header and provide easy ways to format streams
without needing to manually manage spacing or decimal places.

Manipulators are generally used to:


 Control the width of the output.
 Set precision for floating-point numbers.
 Change the format of the output (such as displaying numbers in different bases).
 Modify how text is aligned or how newline characters are handled.

Here are some commonly used stream manipulators:

1. std::endl

Function: Inserts a newline character ('\n') and flushes the stream. Inserts a newline
character and flushes the output buffer.

Example:

std::cout << "Hello, World!" << std::endl;

Example:-

#include <iostream>

using namespace std;

int main() {

cout << "Hello";

cout << endl; // Output a newline and flush the stream

cout << "World!" << endl;

return 0;

endladds a newline character (\n) and flushes the output stream, ensuring that the output is
immediately written to the console or file.
2. setprecision(n)

 Purpose: Sets the precision (number of digits) to be used for floating-point numbers. Sets the
precision of floating-point numbers

Usage: It controls how many digits are displayed after the decimal point.

#include <iostream>

#include <iomanip> // Required for manipulators

using namespace std;

int main() {

double pi = 3.14159265358979;

cout << setprecision(4) << pi << endl; // Output will show 3.142 (4 significant digits)

return 0;

Here, setprecision(4) limits the number of significant digits to 4.

3. fixed and scientific

 Purpose: These manipulators change the format of floating-point numbers.


o fixed: Displays floating-point numbers in fixed-point notation (i.e., standard decimal
form).
o Forces floating-point numbers to be displayed in fixed-point notation.
o scientific: Displays floating-point numbers in scientific notation.
o scientific forces the output to display the number in scientific notation.

#include <iostream>

#include <iomanip> // Required for manipulators


using namespace std;

int main() {

double value = 12345.6789;

cout << fixed << setprecision(2) << value << endl; // Fixed notation with 2 decimals

cout << scientific << setprecision(2) << value << endl; // Scientific notation with 2
decimals

return 0;

4.Setw(n)

 Function: Sets the width of the next input/output field.


 Sets the width of the next input/output.
 It specifies the minimum number of characters to be used when displaying the value.

Example:-

#include <iostream>

#include <iomanip> // Required for manipulators

using namespace std;

int main() {

int num = 42;

cout << setw(5) << num << endl; // Output will be right-aligned with width of 5

return 0;

In this example, setw(5) ensures that the output has a width of 5 characters. If the number is
smaller, it will be padded with spaces to the left.

5. left, right, and internal

 Purpose: These manipulators control the alignment of output within a specific width.
o left: Left-aligns the output.
o right: Right-aligns the output (default for most output).
o internal: Aligns the output with the sign or number at the center and the padding at
the right.
o aligns output to the left or right within the field width.
o Example-

#include <iostream>

#include <iomanip> // Required for manipulators

using namespace std;

int main() {

int num = 42;

cout << left << setw(10) << num << endl; // Left-aligned output

cout << right << setw(10) << num << endl; // Right-aligned output

cout << internal << setw(10) << num << endl; // Internal-aligned output (spaces before
number)

return 0;

In this example:

 left aligns the number to the left within a field of width 10.
 right aligns the number to the right.
 internal places the number in the middle, padding the space before the number.

6. std::showbase

 Function: Shows the base of the number (e.g., 0x for hexadecimal, 0 for octal).
 Example:

#include <iostream>

#include <iomanip>

int main() {
int number = 255;

std::cout << std::showbase << std::hex << number << std::endl;

return 0;

7. flush

 Purpose: Forces the output buffer to be flushed, ensuring that any buffered output is written
immediately.

#include <iostream>

using namespace std;

int main() {

cout << "Hello";

cout.flush(); // Explicitly flushes the output buffer

cout << " World!" << endl;

return 0;

flush ensures that "Hello" is immediately output to the console, even if buffering occurs.

3. Explain what is fstream, ifstream and ofstream with help of example.


Ans- In C++, file handling is done using streams, and the standard library provides three primary
classes for managing file input and output:

In C++, fstream, ifstream, and ofstream are part of the standard library and are used for
file handling. They are defined in the <fstream> header file. Here's a brief overview of each:

 fstream: This is the base class for both input and output file streams.
 ifstream: This is used for input (reading) from files.
 ofstream: This is used for output (writing) to files.

1. fstream

fstream is the base class for file input and output streams. It allows both reading from and
writing to files. You can use it when you want to both read from and write to a file.

Syntax:

#include <fstream>

fstream file("filename");

Example of fstream:
#include <iostream>

#include <fstream> // Required for file handling

using namespace std;

int main() {

// Open file for both reading and writing

fstream file("example.txt", ios::in | ios::out);

// Check if the file is open

if (!file) {

cout << "Error opening the file!" << endl;

return 1;

// Writing to the file

file << "This is a test line written by fstream." << endl;

// Move the file pointer to the beginning

file.seekg(0, ios::beg); // Seek to the beginning of the file


// Reading from the file

string line;

while (getline(file, line)) {

cout << line << endl;

file.close(); // Close the file

return 0;

In this example:

 The fstream object is opened for both input and output (ios::in | ios::out).
 We write a line to the file and then read it back.
 Used for input file operations (reading from a file).

2. ifstream

ifstream (Input File Stream) is used for reading from files. It is derived from istream and
allows you to open a file for reading purposes only.

Syntax:

#include <fstream>

ifstream file("filename");

Example of ifstream:

#include <iostream>

#include <fstream> // Required for file handling

using namespace std;


int main() {

ifstream file("example.txt"); // Open the file for reading

// Check if the file is open

if (!file) {

cout << "Error opening the file!" << endl;

return 1;

string line;

// Read and print each line from the file

while (getline(file, line)) {

cout << line << endl;

file.close(); // Close the file

return 0;

3. ofstream

ofstream (Output File Stream) is used for writing to files. It is derived from ostream and allows
you to open a file for writing only. If the file does not exist, it is created. If it already exists, the
file is cleared (overwritten).

Syntax:

#include <fstream>
ofstream file("filename");

Example of ofstream:

#include <iostream>

#include <fstream> // Required for file handling

using namespace std;

int main() {

ofstream file("output.txt"); // Open the file for writing

// Check if the file is open

if (!file) {

cout << "Error opening the file!" << endl;

return 1;

// Writing to the file

file << "This is the first line in the output file." << endl;

file << "This is the second line in the output file." << endl;

file.close(); // Close the file

return 0;

}.

In this example:

 ofstream is used to open a file for writing.


 The program writes two lines of text to the file output.txt.
Using ofstream: The program writes text to the file example.txt.
Using ifstream: The program reads the contents of the file and prints it to the console.

Using fstream: The program opens the file for both reading and writing. It appends new text
to the end of the file and then reads the updated content.

fstream is used when you need both reading and writing functionality.
ifstream is for input (reading from a file).
ofstream is for output (writing to a file). Each class is useful depending on the task: reading,
writing, or both.

Q.5 Solve any Two of the following.

1. Describe Functional Template.

Ans- Functional Template in C++

A functional template is a way of defining a function that can work with any data type. This is
achieved by using template parameters, which allow the function to be type-independent. It
enables code reusability and type safety, making it easier to work with different data types
without having to write multiple versions of the same function.

A functional template in C++ refers to a template that is used to define a function that works with a
variety of data types, rather than a single type. This allows a function to be more flexible and reusable by
operating on different types without needing to overload the function manually for each type.

In C++, templates enable generic programming, which allows you to write a function or class
once and use it with many different types. Templates can be used for functions (function
templates) and classes (class templates).

Function Templates

A function template defines a generic function that can work with any data type. The template
syntax allows you to define a function that takes one or more parameters of generic types and
performs operations on them, just like regular functions.

Basic Syntax

The syntax for defining a functional template in C++ is:

template <typename T>

ReturnType FunctionName(T parameter) {

// Function implementation
}

Here, T is a placeholder for any data type, and it will be replaced with the actual type when the
function is called.

Example: Template Function for Finding Maximum

Here's a simple example of a template function that finds the maximum of two values:

#include <iostream>

using namespace std;

// Template function definition

template <typename T>

T findMax(T a, T b) {

return (a > b) ? a : b;

int main() {

// Using the template function with integers

int x = 10, y = 20;

cout << "Max of " << x << " and " << y << " is " << findMax(x, y) << endl;

// Using the template function with doubles

double p = 15.5, q = 10.3;

cout << "Max of " << p << " and " << q << " is " << findMax(p, q) << endl;

// Using the template function with characters

char c1 = 'A', c2 = 'B';

cout << "Max of " << c1 << " and " << c2 << " is " << findMax(c1, c2) << endl;

return 0;

}
In this example, the findMax function template takes two parameters of the same type T and
returns the maximum of the two. The function can be used with different data types, such as
integers, doubles, and characters, without having to write separate functions for each type.

Advantages of Functional Templates

 Code Reusability: Write a single function that works with multiple data types.
 Type Safety: The compiler ensures that the correct data types are used, reducing the risk
of type-related errors.
 Flexibility: Function templates can handle any type of data, including user-defined types,
as long as they support the operations used in the template.
 Maintainability: Easier to maintain and update code since changes are made in one
place.

 A function template is a powerful feature in C++ that allows you to define functions that
work with any data type, making your code more flexible and reusable. Templates help in
implementing generic algorithms and data structures, reducing code duplication and
improving maintainability. Additionally, template specialization can be used to
customize templates for specific data types when necessary.

 Function Overriding in Templates (C++)

Function overriding is a feature in object-oriented programming (OOP) that allows a subclass


to provide its specific implementation of a method that is already defined in its base class.
However, function overriding in C++ is different from function templates since templates
are not inherently related to object-oriented concepts. That said, we can simulate the behavior
of function overriding in templates when dealing with inheritance and polymorphism.

Basic concept of function Overriding

Function overriding occurs when a function in a base class is redefined in a derived class. The
new function in the derived class has the same signature (name, parameters, and return type) as
the function in the base class but provides a different implementation.

Syntax of Function Overriding

For function overriding to occur, the base class function must be marked with virtual and the
derived class function must have the same signature. Here’s the basic syntax:
Base Class:
class Base {

public:

virtual void func() {

// Base class implementation

};

Derived Class:

class Derived : public Base {

public:

void func() override { // Override the base class function

// Derived class implementation

};

Example:-

#include <iostream>

using namespace std;

// Base class template

template <typename T>

class Base {

public:

virtual void print() { // Virtual function

cout << "Base class print function" << endl;

};
// Derived class template

template <typename T>

class Derived : public Base<T> {

public:

// Function overriding in the derived class

void print() override {

cout << "Derived class print function" << endl;

};

int main() {

// Create an object of the Derived class

Derived<int> d;

d.print(); // Calls the overridden print function in Derived class

// Base class object

Base<int> b;

b.print(); // Calls the print function in Base class

return 0;

Function Overriding and Templates

In function templates, the overriding concept is the same as in non-template classes:


 A base template function (or base class function) is virtual and can be overridden in a
derived class.
 The derived class provides its own implementation of the function, which will be called
based on the object type used.

Function overriding in template classes in C++ works the same way as in regular classes. You can
override virtual functions in a derived template class by providing a new implementation. This allows the
derived class to provide a customized version of a function that is defined in the base class, and it works
seamlessly with the power of templates, allowing for flexibility and reusability with various data types.

3. Explain STL Containers.

Ans- The Standard Template Library (STL) in C++ is a powerful set of template classes and functions
that provides common data structures, algorithms, and utilities for working with collections of data. STL
is designed to help developers write efficient, reusable, and easy-to-understand code by providing
standardized, generic solutions for common programming tasks. It was introduced in C++ Standard
Library to make programming easier and more consistent across applications.

The Standard Template Library (STL) is a powerful feature of the C++ programming language. It provides
a set of common classes and interfaces for various data structures and algorithms.

Components of STL

STL consists of three main components:

1. Containers
2. Algorithms
3. Iterators

1. Containers

Containers are objects that store collections of data. The STL provides a variety of container
types, each suited for different tasks and performance requirements. Containers come in two
primary categories: sequence containers and associative containers.

1.2. Sequence containers- in the Standard Template Library (STL) are designed to store elements
in a linear sequence. They provide ways to access elements sequentially and are useful for scenarios
where you need to maintain the order of elements. Here are some common sequence containers:

 Vector

 A dynamic array that can resize itself automatically when needed.


 Supports random access (constant time) to elements.
 Efficient at inserting and deleting elements at the end.

 List

 A doubly linked list that allows efficient insertion and deletion at both ends and in the
middle.
 No random access (i.e., accessing an element by index requires traversal).

 Deque (Double-Ended Queue)

 Allows insertion and deletion at both ends in constant time.


 Supports random access to elements.
 Typically implemented as a sequence of fixed-size arrays.

 Array

A fixed-size array that doesn't support dynamic resizing.

Provides fast access to elements with constant time complexity.

1. Vector

A vector is a dynamic array that can resize itself automatically when needed.

Syntax:

#include <vector>

std::vector<int> myVector;

example-

#include <iostream>

#include <vector>

int main() {

std::vector<int> myVector = {1, 2, 3, 4, 5};

// Adding an element to the end


myVector.push_back(6);

// Accessing elements

for (int i = 0; i < myVector.size(); ++i) {

std::cout << myVector[i] << " ";

return 0;

2. List

A list is a doubly linked list that allows efficient insertion and deletion at both ends and in the
middle.

Syntax:

#include <list>

std::list<int> myList;

example-

#include <iostream>

#include <list>

int main() {

std::list<int> myList = {1, 2, 3, 4, 5};

// Adding an element to the end

myList.push_back(6);

// Accessing elements

for (int value : myList) {


std::cout << value << " ";

return 0;

3. Deque (Double-Ended Queue)

A deque allows insertion and deletion at both ends in constant time.

Syntax:

#include <deque>

std::deque<int> myDeque;

example-

#include <iostream>

#include <deque>

int main() {

std::deque<int> myDeque = {1, 2, 3, 4, 5};

// Adding an element to the front and back

myDeque.push_front(0);

myDeque.push_back(6);

// Accessing elements

for (int value : myDeque) {

std::cout << value << " ";

return 0;

}
4. Array

An array is a fixed-size array that doesn't support dynamic resizing.

Syntax:

#include <array>

std::array<int, 5> myArray;

example-

#include <iostream>

#include <array>

int main() {

std::array<int, 5> myArray = {1, 2, 3, 4, 5};

// Accessing elements

for (int i = 0; i < myArray.size(); ++i) {

std::cout << myArray[i] << " ";

return 0;

2.Associative Containers: These store data in a sorted order, often implemented as balanced trees (like
red-black trees). They are optimized for fast searching and sorting by keys.

 set: A container of unique elements, automatically sorted.


 map: A container of key-value pairs, where the keys are unique and sorted.
 multiset: Similar to set, but allows duplicate elements.

 multimap: Similar to map, but allows duplicate keys.

1. Map
A map is a collection of key-value pairs with unique keys, implemented as a balanced binary
search tree.

Syntax:

#include <map>

std::map<int, std::string> myMap;

example-

#include <iostream>

#include <map>

int main() {

std::map<int, std::string> myMap;

// Inserting elements

myMap[1] = "One";

myMap[2] = "Two";

myMap[3] = "Three";

// Accessing elements

for (const auto& pair : myMap) {

std::cout << pair.first << " => " << pair.second << "\n";

return 0;

2. Set

A set is a collection of unique elements, implemented as a balanced binary search tree.


Syntax:

#include <set>

std::set<int> mySet;

example-

#include <iostream>

#include <set>

int main() {

std::set<int> mySet = {1, 2, 3, 4, 5};

// Inserting an element

mySet.insert(6);

// Accessing elements

for (int value : mySet) {

std::cout << value << " ";

return 0;

3. Unordered Map

An unordered_map is similar to a map, but uses a hash table for faster average-case access time.

Syntax:

#include <unordered_map>

std::unordered_map<int, std::string> myUnorderedMap;

example-

#include <iostream>
#include <unordered_map>

int main() {

std::unordered_map<int, std::string> myUnorderedMap;

// Inserting elements

myUnorderedMap[1] = "One";

myUnorderedMap[2] = "Two";

myUnorderedMap[3] = "Three";

// Accessing elements

for (const auto& pair : myUnorderedMap) {

std::cout << pair.first << " => " << pair.second << "\n";

return 0;

4. Unordered Set

An unordered_set is similar to a set, but uses a hash table for faster average-case access time.

Syntax:

#include <unordered_set>

std::unordered_set<int> myUnorderedSet;

example-

#include <iostream>

#include <unordered_set>

int main() {
std::unordered_set<int> myUnorderedSet = {1, 2, 3, 4, 5};

// Inserting an element

myUnorderedSet.insert(6);

// Accessing elements

for (int value : myUnorderedSet) {

std::cout << value << " ";

return 0;

4.1 Unordered Containers: These use hash tables for storing data and provide faster lookups,
but the order of elements is not guaranteed.

 unordered_set: A set of unique elements, stored using a hash table.


 unordered_map: A map of key-value pairs, where the keys are unique, using hash tables.
 unordered_multiset: A set of elements that may have duplicates, stored using hash
tables.
 unordered_multimap: A map of key-value pairs that may have duplicate keys, stored
using hash tables.

  Map and Set are useful when you need sorted data.
  Unordered Map and Unordered Set offer faster access times for unsorted data.

4. Container Adapters:
These provide specific interfaces to other container types for specific use cases.
Container adapters in the Standard Template Library (STL) provide restricted interfaces to
sequence containers. They are designed to provide specific functionality by leveraging
underlying sequence containers (like vector, deque, or list). There are three main container
adapters: stack, queue, and priority_queue.

1. Stack

A stack is a container adapter that follows the Last In, First Out (LIFO) principle.

Syntax:

#include <stack>
#include <vector> // You can use vector, deque, or list as the underlying container.

std::stack<int, std::vector<int>> myStack;

example-

#include <iostream>

#include <stack>
#include <vector>

int main() {
std::stack<int, std::vector<int>> myStack;

// Pushing elements onto the stack


myStack.push(10);
myStack.push(20);
myStack.push(30);

// Accessing and removing elements from the stack


while (!myStack.empty()) {
std::cout << myStack.top() << " ";
myStack.pop();
}
return 0;
}

Queue

A queue is a container adapter that follows the First In, First Out (FIFO) principle.

Syntax:

#include <queue>
#include <deque> // You can use deque or list as the underlying container.

std::queue<int, std::deque<int>> myQueue;

Example:

#include <iostream>
#include <queue>
#include <deque>

int main() {
std::queue<int, std::deque<int>> myQueue;
// Enqueueing elements
myQueue.push(10);
myQueue.push(20);
myQueue.push(30);

// Accessing and removing elements from the queue


while (!myQueue.empty()) {
std::cout << myQueue.front() << " ";
myQueue.pop();
}
return 0;
}

3. Priority Queue

A priority_queue is a container adapter that maintains a heap to keep elements in a specific


order.

Syntax:

#include <queue>
#include <vector> // You can use vector as the underlying container.

std::priority_queue<int, std::vector<int>> myPriorityQueue;

Example:
#include <iostream>
#include <queue>
#include <vector>

int main() {
std::priority_queue<int, std::vector<int>> myPriorityQueue;

// Adding elements to the priority queue


myPriorityQueue.push(10);
myPriorityQueue.push(30);
myPriorityQueue.push(20);

// Accessing and removing elements from the priority queue


while (!myPriorityQueue.empty()) {
std::cout << myPriorityQueue.top() << " ";
myPriorityQueue.pop();
}
return 0;
}
These examples show how container adapters can be used to provide specific functionality using
underlying sequence containers. They are particularly useful when you need to restrict access to
elements to follow specific principles, such as LIFO for stack and FIFO for queue.

4. Write short note on Exceptional Handling.

Ans- In C++, exceptions provide a way to handle runtime errors or unusual situations that can
arise during the execution of a program, like invalid input, file access errors, or memory
allocation failures. They allow you to separate the error-handling code from the normal flow of
your program, making your code more robust and easier to maintain.

In C++, exceptions are a powerful mechanism for handling errors and other exceptional
situations. They allow the programmer to separate error-handling code from regular code,
making the program easier to read and maintain. Here's an overview of how exceptions work in
C++:

Exception Handling Mechanism in C++

The C++ exception handling mechanism uses three keywords:

1. try
2. throw
3. catch

These are used together to throw exceptions when an error occurs, and then catch those exceptions
to handle them in a controlled way.

Basic Concepts of Exception Handling

1. Throwing an Exception: When an error occurs, an exception is thrown using the throw
keyword.
2. Catching an Exception: Exceptions are caught using catch blocks, which are associated
with a try block that contains the code that might throw an exception.
3. Exception Objects: Exceptions can be of any type, but it's common to use standard
exception classes or user-defined exception classes.

Syntax

try {

// Code that may throw an exception

// ...
throw exception; // Throw an exception

} catch (exception_type1 e1) {

// Handle exception of type exception_type1

// ...

} catch (exception_type2 e2) {

// Handle exception of type exception_type2

// ...

1. try Block

The try block is where you place code that might throw an exception. The code inside the try
block is executed normally, but if an exception is thrown, the control is transferred to the
matching catch block.

2. throw Statement

The throw keyword is used to throw an exception. When an exception is thrown, the normal
flow of control is interrupted, and the program looks for a matching catch block to handle it.

3. catch Block

The catch block is used to catch and handle exceptions that are thrown. It is placed after the try
block and specifies the type of exception it can handle. Multiple catch blocks can be used to
handle different types of exceptions.

#include <iostream>

#include <stdexcept> // For standard exception classes

// Function that throws an exception

void divide(int a, int b) {

if (b == 0) {

throw std::runtime_error("Division by zero error");


}

std::cout << "Result: " << a / b << std::endl;

int main() {

try {

// Code that may throw an exception

divide(10, 0);

} catch (const std::runtime_error& e) {

// Handle runtime_error exception

std::cerr << "Exception caught: " << e.what() << std::endl;

} catch (...) {

// Handle any other exceptions

std::cerr << "An unknown exception was caught." << std::endl;

std::cout << "Program continues..." << std::endl;

return 0;

Explanation

1. Throwing an Exception: In the divide function, if the denominator (b) is zero, a


std::runtime_error exception is thrown using the throw keyword.
2. Catching an Exception: The try block in the main function contains the code that might
throw an exception. If an exception is thrown, the corresponding catch block is
executed.
o The first catch block catches exceptions of type std::runtime_error.
o The second catch block (with ...) catches any other types of exceptions.

Standard Exception Classes

C++ provides several standard exception classes in the <stdexcept> header, such as:

 std::exception: Base class for all standard exceptions.


 std::runtime_error: Represents errors that occur at runtime.
 std::logic_error: Represents logical errors in the program.
 std::out_of_range: Represents errors when accessing elements out of range.

 f an exception is thrown inside a function and not caught there, it will propagate to the
calling function, and so on, until it is caught or it reaches the main() function.

If uncaught exceptions reach main(), the program terminates and may produce an error
message.

Exception handling is a crucial part of writing robust and reliable C++ programs. It allows you to
handle errors gracefully and ensures that your program can recover from unexpected situations.

Exceptions in C++ provide a powerful way to handle errors and exceptional situations in your
programs. By using try, throw, and catch, you can write robust code that gracefully handles
errors without interrupting the normal flow of the program. The key benefits of exceptions are that
they separate error-handling logic from regular code and provide an efficient mechanism for
managing runtime errors. Proper exception handling improves code maintainability, reliability, and
readability.

You might also like