0% found this document useful (0 votes)
10 views57 pages

VIMP OOP

The document discusses various C++ programming concepts including operator overloading, virtual functions, type conversions, polymorphism, pure virtual functions, and virtual destructors. It provides explanations, rules, and example programs for each concept, illustrating their usage and importance in object-oriented programming. Key topics covered include the need for operator overloading, implementation of virtual functions, type casting, and the significance of abstract base classes.

Uploaded by

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

VIMP OOP

The document discusses various C++ programming concepts including operator overloading, virtual functions, type conversions, polymorphism, pure virtual functions, and virtual destructors. It provides explanations, rules, and example programs for each concept, illustrating their usage and importance in object-oriented programming. Key topics covered include the need for operator overloading, implementation of virtual functions, type casting, and the significance of abstract base classes.

Uploaded by

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

UNIT 1

1. Explain need of operator overloading. What are the rules to be followed when overloading
an operator in C++?
ANS: Need of Operator Overloading in C++
Make Custom Types Work Like Built-In Types:
 For example, if you define a Complex number class, you may want to use + to add two
complex numbers just like you do with int.
Improve Code Readability and Clarity:
 Instead of calling a member function like c1.add(c2), you can write c1 + c2, which is easier to
read and write.
Enable Natural Syntax for Custom Classes:
 Especially useful in classes that represent:
o Complex numbers
o Vectors
o Matrices
o Fractions
o Strings
o File streams
o Iterators
Increase Code Reusability:
 Overloaded operators make code more modular and object-oriented by reusing the same
operator for different object behaviors.
 Rules for Operator Overloading in C++
 While overloading operators in C++, the following rules must be followed:
Rule
Rule Description
No.
1 Only existing C++ operators can be overloaded. You cannot create new operators.
At least one operand must be a user-defined type (e.g., a class or struct). You cannot
2
overload operators for only built-in types.
3 You cannot change the precedence, associativity, or arity of operators.
Certain operators cannot be overloaded, such as: ::, ., .*, sizeof, ?:, typeid, and the cast
4
operators like static_cast.
Overloaded operators should behave logically and intuitively, matching their expected use.
5
For example, + should add, not subtract.
6 You can overload an operator either as a member function or a friend function.
For assignment (=), function call (()), subscript ([]), and member access (->) — must be
7
overloaded as member functions only.

2. How virtual functions are implemented in C++? Explain with help of a program.
ANS: virtual functions allow runtime polymorphism, enabling the correct function to be called based
on the object type (not pointer/reference type).
Behind the scenes, C++ uses a mechanism called the vtable (virtual table) to implement virtual
functions.
How It Works Internally:
1. vtable (Virtual Table):
o A table of function pointers maintained per class.
o Contains addresses of the virtual functions that can be called on an object of that
class.
2. vptr (Virtual Pointer):
o Each object of a class with virtual functions contains a hidden pointer (vptr) pointing
to the class's vtable.
3. Runtime Decision:
o When a virtual function is called using a base class pointer, the vptr helps decide
which version of the function (base or derived) to call at runtime.

� Example Program:
#include <iostream>
using namespace std;

class Base {
public:
virtual void show() {
cout << "Base class show() function" << endl;
}
};

class Derived : public Base {


public:
void show() override {
cout << "Derived class show() function" << endl;
}
};

int main() {
Base* bptr;
Derived d;

bptr = &d; // Base pointer points to Derived object


bptr->show(); // Calls Derived's show() due to virtual function

return 0;
}

� Output:
Derived class show() function

3. Define a class string and use binary overloaded operator (= =) to compare two strings
ANS: #include <iostream>
#include <cstring> // For strcmp()
using namespace std;

class MyString {
char str[100];
public:
// Constructor
MyString(const char* s = "") {
strcpy(str, s);
}

// Overload == operator
bool operator==(MyString& s) {
return strcmp(str, s.str) == 0;
}

// Display function
void display() {
cout << str << endl;
}
};

int main() {
MyString s1("hello");
MyString s2("hello");
MyString s3("world");

if (s1 == s2)
cout << "s1 and s2 are equal." << endl;
else
cout << "s1 and s2 are not equal." << endl;

if (s1 == s3)
cout << "s1 and s3 are equal." << endl;
else
cout << "s1 and s3 are not equal." << endl;

return 0;
}
Output:
s1 and s2 are equal.
s1 and s3 are not equal.

4. Explain what is type conversions? Define implicit type casting and explicit type casting
with example.
ANS: Type conversion is the process of converting a value from one data type to another. It occurs
when different data types are mixed in an expression or when a value is assigned to a variable of a
different type.
There are two types of type conversions in C++:
1. Implicit Type Casting (Type Promotion)
2. Explicit Type Casting (Type Casting by the Programmer)

� 1. Implicit Type Casting (Automatic Type Conversion)


 Performed automatically by the compiler.
 Occurs when assigning a smaller data type to a larger one (e.g., int to float).
 No data loss occurs.
� Example:
#include <iostream>
using namespace std;

int main() {
int a = 10;
float b;

b = a; // int to float (implicit casting)

cout << "Value of b: " << b << endl;


return 0;
}
� Output:
Value of b: 10

� 2. Explicit Type Casting (Manual Type Conversion)


 Done manually by the programmer using type cast operators.
 Used when we need to force a conversion (e.g., float to int).
 May cause data loss.
� Example:
#include <iostream>
using namespace std;

int main() {
float x = 10.75;
int y;

y = (int)x; // Explicit type casting

cout << "Value of y: " << y << endl;


return 0;
}
� Output:
yaml
Copy code
Value of y: 10

5. Explain Virtual destructor with the help of a program.


ANS: when you use inheritance and base class pointers, if the destructor is not virtual, deleting a
derived class object through a base class pointer can cause undefined behavior — typically, only the
base class destructor will be called, not�the�derived�class’s, leading to resource leaks.
� Virtual Destructor
A virtual destructor ensures that both base and derived class destructors are called in the correct
order when deleting an object via a base class pointer.

� Example Without Virtual Destructor (Wrong Behavior)

#include <iostream>
using namespace std;

class Base {
public:
~Base() {
cout << "Base destructor called" << endl;
}
};

class Derived : public Base {


public:
~Derived() {
cout << "Derived destructor called" << endl;
}
};

int main() {
Base* ptr = new Derived(); // Base pointer to Derived object
delete ptr; // Only Base destructor is called
return 0;
}
Output:
Base destructor called
Only base destructor is called. Derived destructor is skipped.

Correct Example Using Virtual Destructor

#include <iostream>
using namespace std;

class Base {
public:
virtual ~Base() {
cout << "Base destructor called" << endl;
}
};

class Derived : public Base {


public:
~Derived() {
cout << "Derived destructor called" << endl;
}
};
int main() {
Base* ptr = new Derived();
delete ptr; // Both destructors are now called correctly
return 0;
}
Output:
Derived destructor called
Base destructor called

6. Write a C++ program to overload binary operator ‘+’ to add two complex numbers using
member function and friend function
ANS:
1. Using Member Function
#include <iostream>
using namespace std;

class Complex {
float real, imag;

public:
Complex(float r = 0, float i = 0) {
real = r;
imag = i;
}

// Overload '+' using member function


Complex operator+(const Complex& c) {
return Complex(real + c.real, imag + c.imag);
}

void display() {
cout << real << " + " << imag << "i" << endl;
}
};

int main() {
Complex c1(3.5, 2.5), c2(1.5, 4.5), c3;

c3 = c1 + c2;

cout << "Sum (Member Function): ";


c3.display();

return 0;
}
2. Using Friend Function
#include <iostream>
using namespace std;

class Complex {
float real, imag;

public:
Complex(float r = 0, float i = 0) {
real = r;
imag = i;
}

// Friend function declaration


friend Complex operator+(Complex c1, Complex c2);

void display() {
cout << real << " + " << imag << "i" << endl;
}
};

// Friend function definition


Complex operator+(Complex c1, Complex c2) {
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

int main() {
Complex c1(5, 6), c2(2, 3), c3;

c3 = c1 + c2;

cout << "Sum (Friend Function): ";


c3.display();

return 0;
}
Output for Both:
Sum: 6 + 7i

7. Explain Polymorphism and Types of Polymorphism.


ANS: Polymorphism is one of the core concepts in Object-Oriented Programming (OOP), meaning
"many forms." It allows functions or objects to behave differently based on the context — typically
depending on the type of data or object being handled.

� Types of Polymorphism in C++


C++ supports two main types of polymorphism:
� 1. Compile-Time Polymorphism (Static Binding / Early Binding)
 Decision is made at compile time.
 Achieved using:
o Function Overloading
o Operator Overloading
� Example: Function Overloading

#include <iostream>
using namespace std;

class Print {
public:
void show(int a) {
cout << "Integer: " << a << endl;
}

void show(float b) {
cout << "Float: " << b << endl;
}
};

int main() {
Print obj;
obj.show(5);
obj.show(3.14f);
return 0;
}
� Example: Operator Overloading

Complex c3 = c1 + c2; // '+' is overloaded to add two complex numbers

� 2. Run-Time Polymorphism (Dynamic Binding / Late Binding)


 Decision is made at runtime.
 Achieved using:
o Virtual Functions
o Function Overriding
o Pointers or references to base class
� Example: Virtual Function

#include <iostream>
using namespace std;

class Base {
public:
virtual void display() {
cout << "Base display" << endl;
}
};

class Derived : public Base {


public:
void display() override {
cout << "Derived display" << endl;
}
};

int main() {
Base* ptr;
Derived d;
ptr = &d;

ptr->display(); //�Calls�Derived’s�display()�at�runtime
return 0;
}
� Output:

Derived display

8. How do you declare and define a pure virtual function in C++? Explain with help of a
program
ANS: A pure virtual function is a function that has no definition in the base class and must be
implemented by any derived class. It is declared by assigning = 0 at the end of the function
declaration in the base class. A class containing at least one pure virtual function is called an abstract
class, and objects of an abstract class cannot be instantiated directly.

� Syntax:
virtual return_type function_name(parameters) = 0;

� Why Use Pure Virtual Functions?


 To force derived classes to implement a specific function.
 To define an interface in the base class that must be provided by all derived classes (abstract
base class).

� Example Program with Pure Virtual Function:

#include <iostream>
using namespace std;

// Abstract base class


class Shape {
public:
// Pure virtual function (interface)
virtual void draw() = 0; // No implementation here

// Regular function
void display() {
cout << "This is a shape." << endl;
}
};
// Derived class that must implement draw() due to pure virtual function in base class
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

Shape* shape1 = new Circle();


Shape* shape2 = new Rectangle();

shape1->draw(); // Calls Circle's draw()


shape2->draw(); // Calls Rectangle's draw()

delete shape1;
delete shape2;

return 0;
}

� Output:

Drawing a Circle
Drawing a Rectangle

9. What is abstract base class in C++ polymorphism? Explain with program.


ANS: An abstract base class in C++ is a class that cannot be instantiated and is used to define a
common interface for all its derived classes. The key feature of an abstract base class is that it
contains at least one pure virtual function. The pure virtual function is a function that has no
implementation in the base class and must be implemented by any derived class.

� Why Use an Abstract Base Class?


 Enforces a contract: It forces derived classes to provide specific implementations for the
pure virtual functions.
 Common interface: It defines a common interface for derived classes, making polymorphism
easier.
 Cannot instantiate: You cannot create objects of an abstract class, but you can create
pointers to it (often used for dynamic polymorphism).
� Syntax of an Abstract Base Class

class AbstractClass {
public:
virtual void someFunction() = 0; // Pure virtual function
};
 = 0 denotes that the function is pure virtual.
 A class with at least one pure virtual function is considered an abstract class.

� Example Program: Abstract Base Class in C++ Polymorphism

#include <iostream>
using namespace std;

// Abstract Base Class


class Shape {
public:
// Pure virtual function (making Shape an abstract class)
virtual void draw() = 0;

// A normal function
void display() {
cout << "Displaying the shape" << endl;
}
};

// Derived Class: Circle


class Circle : public Shape {
public:
// Implementation of the pure virtual function
void draw() override {
cout << "Drawing a Circle" << endl;
}
};

// Derived Class: Rectangle


class Rectangle : public Shape {
public:
// Implementation of the pure virtual function
void draw() override {
cout << "Drawing a Rectangle" << endl;
}
};

int main() {
// Shape s; // Error: Cannot instantiate an abstract class

// Polymorphism: Pointers to base class


Shape* shape1 = new Circle(); // Pointing to Circle object
Shape* shape2 = new Rectangle(); // Pointing to Rectangle object
// Calling the draw function (which is overridden in the derived classes)
shape1->draw(); // Calls Circle's draw()
shape2->draw(); // Calls Rectangle's draw()

// Using the common display function from the base class


shape1->display();
shape2->display();

delete shape1;
delete shape2;

return 0;
}

� Output:

Drawing a Circle
Drawing a Rectangle
Displaying the shape
Displaying the shape

10. Explain Virtual destructor with the help of a program.


ANS: A virtual destructor is used in C++ to ensure that when an object of a derived class is deleted
through a base class pointer, the destructor of the derived class is called, ensuring proper cleanup of
resources. Without a virtual destructor, only the destructor of the base class would be called,
leading to memory leaks or undefined behavior.
� Why Use Virtual Destructors?
 Polymorphism and Deleting Objects: When you use a base class pointer to delete an object
of a derived class, the correct destructor (of the derived class) must be called to release all
resources allocated by the derived class.
 Without a virtual destructor, the base class destructor is called, and the derived class
destructor does not get invoked, potentially leading to resource leaks (like memory not
being freed).
� Syntax:

virtual ~BaseClass() {
// Destructor code
}
The virtual keyword ensures that the correct destructor is called for the derived class object when
deleted through a base class pointer.

� Example Program with Virtual Destructor:

#include <iostream>
using namespace std;

// Base class
class Base {
public:
Base() {
cout << "Base class constructor" << endl;
}

// Virtual destructor to ensure proper cleanup


virtual ~Base() {
cout << "Base class destructor" << endl;
}
};

// Derived class
class Derived : public Base {
public:
Derived() {
cout << "Derived class constructor" << endl;
}

// Destructor for the derived class


~Derived() override {
cout << "Derived class destructor" << endl;
}
};

int main() {
// Creating a pointer to the base class and assigning it a derived class object
Base* ptr = new Derived();

// Deleting the object


delete ptr; // This will call Derived's destructor, followed by Base's destructor

return 0;
}

� Output:
kotlin
Copy code
Base class constructor
Derived class constructor
Derived class destructor
Base class destructor

11. Write C++ program to demonstrate use of unary operator (- -) overloading using member
function and unary operator overloading (++) using friend function.
ANS: #include <iostream>
using namespace std;

class Counter {
private:
int count;
public:
// Constructor to initialize count
Counter(int c = 0) : count(c) {}

// Unary -- operator overloading (member function)


void operator--() {
--count; // Decrement the count
}

// Display the value of count


void display() {
cout << "Count: " << count << endl;
}

// Friend function to overload the unary ++ operator


friend void operator++(Counter& c);
};

// Friend function to overload unary ++ operator


void operator++(Counter& c) {
++c.count; // Increment the count
}

int main() {
Counter c1(10); // Create a Counter object with initial value 10

cout << "Initial ";


c1.display();

// Use the overloaded -- operator (member function)


--c1; // This will call the operator-- function
cout << "After -- operation: ";
c1.display();

// Use the overloaded ++ operator (friend function)


++c1; // This will call the operator++ function
cout << "After ++ operation: ";
c1.display();

return 0;
}
Output:
Initial Count: 10
After -- operation: Count: 9
After ++ operation: Count: 10
UNIT 4

1. Explain overloading the extraction (>>) and insertion (<<) operators with the help of a
program.
ANS: Overloading Extraction (>>) and Insertion (<<) Operators in C++
In C++, the extraction (>>) and insertion (<<) operators are used with input/output streams:
 cin >> is used for input (extraction).
 cout << is used for output (insertion).
To use these operators with user-defined classes, we need to overload them. This is typically done
using friend functions, so they can access private members of the class.

� Syntax of Overloading:

friend istream& operator>>(istream& in, ClassName& obj);


friend ostream& operator<<(ostream& out, const ClassName& obj);

� Example Program

#include <iostream>
using namespace std;

class Student {
private:
string name;
int rollNo;
float marks;

public:
// Friend function to overload extraction operator >>
friend istream& operator>>(istream& in, Student& s);

// Friend function to overload insertion operator <<


friend ostream& operator<<(ostream& out, const Student& s);
};

// Overloading >> operator (extraction)


istream& operator>>(istream& in, Student& s) {
cout << "Enter name: ";
in >> s.name;
cout << "Enter roll number: ";
in >> s.rollNo;
cout << "Enter marks: ";
in >> s.marks;
return in;
}

// Overloading << operator (insertion)


ostream& operator<<(ostream& out, const Student& s) {
out << "\nStudent Details:\n";
out << "Name: " << s.name << endl;
out << "Roll No: " << s.rollNo << endl;
out << "Marks: " << s.marks << endl;
return out;
}

int main() {
Student s1;

// Use overloaded >> operator


cin >> s1;

// Use overloaded << operator


cout << s1;

return 0;
}

� Output:

Enter name: Rahul


Enter roll number: 101
Enter marks: 88.5

Student Details:
Name: Rahul
Roll No: 101
Marks: 88.5

2. What are File Pointers? Explain seekg() and tellg() functions with syntax.
ANS: file pointers are internal pointers that keep track of the current read or write position in a file
when using file streams (like ifstream, ofstream, or fstream). They are crucial for random access to
file data.
There are two types of file pointers:
1. get pointer – Used for reading from a file (ifstream or fstream in input mode).
2. put pointer – Used for writing to a file (ofstream or fstream in output mode).

� seekg() and tellg() Functions


These functions are used with input file streams (ifstream) to manipulate or report the get pointer
(read position).

� tellg() – Tell Get Pointer


 Returns the current position of the get pointer in the file.
 Useful for tracking where in the file the read operation is currently.
� Syntax:
ifstream fin;
fin.open("file.txt");
int pos = fin.tellg();

� seekg() – Seek Get Pointer


 Moves the get pointer to a specific location in the file.
� Syntax:
fin.seekg(position); // from beginning
fin.seekg(offset, ios::beg); // from beginning
fin.seekg(offset, ios::cur); // from current position
fin.seekg(offset, ios::end); // from end of file

� Example Program

#include <iostream>
#include <fstream>
using namespace std;

int main() {
ifstream fin("example.txt");

if (!fin) {
cout << "File not found!" << endl;
return 1;
}

// Tell current read position (should be 0 at start)


streampos pos = fin.tellg();
cout << "Initial get pointer position: " << pos << endl;

// Move to 5th character from beginning


fin.seekg(5, ios::beg);
cout << "Moved to position 5." << endl;

// Check new position


pos = fin.tellg();
cout << "Current get pointer position: " << pos << endl;

char ch;
fin >> ch;
cout << "Character read: " << ch << endl;

fin.close();
return 0;
}

� Output :

Initial get pointer position: 0


Moved to position 5.
Current get pointer position: 5
Character read: (the 6th character in file)

3. Write a program that emulates the DOS COPY command. That is, it should copy the
contents of a text file (such as any .CPP file) to another file. Invoke the program with two
command-line arguments-the source file and the destination file-like this; C>ocopy
srcfile.cpp destfile.cpp In the program, check that the user has typed the correct number
of command-line arguments, and that the files specified can be opened.
ANS:
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, char* argv[]) {


// Check for correct number of command-line arguments
if (argc != 3) {
cerr << "Usage: ocopy <source_file> <destination_file>" << endl;
return 1;
}

// Open source file for reading


ifstream srcFile(argv[1]);
if (!srcFile) {
cerr << "Error: Cannot open source file '" << argv[1] << "'" << endl;
return 1;
}

// Open destination file for writing


ofstream destFile(argv[2]);
if (!destFile) {
cerr << "Error: Cannot open/create destination file '" << argv[2] << "'" << endl;
return 1;
}

// Copy contents from source to destination


char ch;
while (srcFile.get(ch)) {
destFile.put(ch);
}

cout << "File copied successfully from " << argv[1] << " to " << argv[2] << endl;

// Close files
srcFile.close();
destFile.close();

return 0;
}
4. Explain the errror handling in file I/O.
ANS: Error Handling in File I/O in C++
In C++, file I/O operations can fail for many reasons—such as:
 File doesn't exist
 Permission denied
 Disk is full
 End of file (EOF) reached
 Read/write errors
To handle such issues, C++ provides error flags and functions associated with file stream objects
(ifstream, ofstream, fstream).

� Common File Stream Error Functions


Function Description
fail() Returns true if an input/output operation fails (e.g., type mismatch).
eof() Returns true if the end-of-file is reached during input.
bad() Returns true if a read/write operation fails due to a serious error.
good() Returns true if none of the above errors occurred.
clear() Resets all error flags.

� Example: Error Handling in File I/O

#include <iostream>
#include <fstream>
using namespace std;

int main() {
ifstream file("data.txt");

// Check if file is opened


if (!file) {
cerr << "Error: File could not be opened!" << endl;
return 1;
}

char ch;
while (file.get(ch)) {
cout << ch;
}

// Check for EOF


if (file.eof()) {
cout << "\nEnd of file reached." << endl;
}
// Check for read failure (e.g., type mismatch)
else if (file.fail()) {
cout << "\nRead failed (failbit set)." << endl;
}
// Check for serious error (e.g., hardware failure)
else if (file.bad()) {
cout << "\nSerious I/O error (badbit set)." << endl;
}

file.close();
return 0;
}

� Output (if file exists):

<contents of data.txt>
End of file reached.

5. Explain the two ways in which files can be opened, open () and Using constructor with a
program.
ANS: 1. Using Constructor
When an object of ifstream, ofstream, or fstream is created, a file can be opened by passing the
filename and mode directly to the constructor.
� Syntax:
cpp
Copy code
ifstream fin("file.txt"); // Open file for reading
ofstream fout("file.txt"); // Open file for writing

✅2. Using open() Function


You can also declare the file stream object first and then call the open() function separately.
� Syntax:

ifstream fin;
fin.open("file.txt");

� Example Program Demonstrating Both Methods

#include <iostream>
#include <fstream>
using namespace std;

int main() {
// --- Using Constructor ---
ofstream fout("example1.txt"); // Open file using constructor
if (!fout) {
cout << "Error opening file using constructor!" << endl;
return 1;
}
fout << "This file was opened using constructor.\n";
fout.close();

// --- Using open() Function ---


ofstream fout2;
fout2.open("example2.txt"); // Open file using open()
if (!fout2) {
cout << "Error opening file using open()!" << endl;
return 1;
}
fout2 << "This file was opened using open() function.\n";
fout2.close();

cout << "Files created and written successfully." << endl;


return 0;
}

6. What is stream? Explain types of stream available in C++ i.e istream, ostream, ifstream and
ofstream.
ANS: a stream is an abstraction that represents a flow of data — either input (to the program) or
output (from the program). You can think of it as a sequence of characters that flows like a stream of
water.
There are two main types:
 Input Stream (istream): For reading data into the program.
 Output Stream (ostream): For writing data out of the program.
Streams are used with console I/O and file I/O in C++.

� Types of Streams in C++


Stream Type Description Header Usage
istream Base class for all input streams <iostream> cin >> var;
ostream Base class for all output streams <iostream> cout << "Text";
ifstream Input file stream (for reading files) <fstream> ifstream fin("file.txt");
ofstream Output file stream (for writing files) <fstream> ofstream fout("file.txt");

� Descriptions
� 1. istream (Input Stream)
 Used to read input from standard input (keyboard).
 Common object: cin

int x;
cin >> x; // Input from keyboard

� 2. ostream (Output Stream)


 Used to display output to standard output (screen).
 Common object: cout

cout << "Hello, World!"; // Output to screen

� 3. ifstream (Input File Stream)


 Used to read data from files.
 Defined in <fstream>.
ifstream fin("data.txt");
string name;
fin >> name;
fin.close();

� 4. ofstream (Output File Stream)


 Used to write data to files.
 Defined in <fstream>.

ofstream fout("output.txt");
fout << "File output";
fout.close();

7. List and Explain different Mode bits used in open() function, while opening a file
ANS: when opening a file using the open() function (with ifstream, ofstream, or fstream), you can
specify mode bits to define how the file should be accessed — read, write, append, binary, etc.
These mode bits are defined in the <fstream> header and are passed as arguments to the open()
function.

✅Common File Opening Mode Bits in C++


Mode Bit Description
ios::in Open for reading. Used with ifstream or fstream.
Open for writing. Used with ofstream or fstream. If the file exists, its content is
ios::out
overwritten.
ios::app Append mode. Data is written at the end of file.
ios::ate Go to the end of file after opening, but allow writing anywhere.
ios::trunc Truncate the file if it exists (default with ios::out). Deletes previous content.
ios::binary Open file in binary mode (not text mode).

� Example: Using Mode Bits


#include <iostream>
#include <fstream>
using namespace std;

int main() {
// Open file for writing in append mode
ofstream fout;
fout.open("example.txt", ios::out | ios::app);

if (!fout) {
cout << "Error opening file!" << endl;
return 1;
}

fout << "Adding this line at the end.\n";


fout.close();
return 0;
}

8. Define a class Book that has three attributes viz bookname, author and price. Write a C++
Program that writes an object to a file and reads an object from a file.
ANS: #include <iostream>
#include <fstream>
using namespace std;

class Book {
private:
char bookname[50];
char author[50];
float price;

public:
void getData() {
cout << "Enter book name: ";
cin.getline(bookname, 50);
cout << "Enter author name: ";
cin.getline(author, 50);
cout << "Enter price: ";
cin >> price;
cin.ignore(); // to clear the newline character
}

void displayData() {
cout << "Book Name : " << bookname << endl;
cout << "Author : " << author << endl;
cout << "Price : " << price << endl;
}
};

int main() {
Book b1;

// Get book details from user


cout << "Enter book details:\n";
b1.getData();

// Writing object to file


ofstream fout("book.dat", ios::binary);
if (!fout) {
cout << "Error opening file for writing!" << endl;
return 1;
}
fout.write((char*)&b1, sizeof(b1));
fout.close();
cout << "\nBook written to file successfully.\n";

// Reading object from file


Book b2;
ifstream fin("book.dat", ios::binary);
if (!fin) {
cout << "Error opening file for reading!" << endl;
return 1;
}
fin.read((char*)&b2, sizeof(b2));
fin.close();

cout << "\nBook read from file:\n";


b2.displayData();

return 0;
}
Output:
Enter book details:
Enter book name: C++ Primer
Enter author name: Lippman
Enter price: 599.99

Book written to file successfully.

Book read from file:


Book Name : C++ Primer
Author : Lippman
Price : 599.99

9. What do you mean by File Handling? Explain following functions with syntax and an
example. i) open() ii) read() iii) write().
ANS: File handling in C++ refers to reading from and writing to files on the disk using streams
(ifstream, ofstream, fstream). It allows storing data permanently, reading it back, and modifying it as
needed.

� i) open() Function
Purpose: Opens a file in a specified mode.
Syntax:
stream_object.open("filename", mode);
Modes include:
 ios::in →�input�(read)
 ios::out →�output�(write)
 ios::app →�append
 ios::binary →�binary�mode
 ios::ate →�go�to�end�of file
Example:
ofstream fout;
fout.open("data.txt", ios::out);
fout << "Hello, File!";
fout.close();

� ii) write() Function


Purpose: Writes binary data from memory to file.
Syntax:
file.write((char*)&object, sizeof(object));

Example:
class Student {
char name[30];
int roll;
public:
void getData() {
strcpy(name, "John");
roll = 101;
}
};

int main() {
Student s;
s.getData();
ofstream fout("student.dat", ios::binary);
fout.write((char*)&s, sizeof(s));
fout.close();
return 0;
}

� iii) read() Function


Purpose: Reads binary data from file into memory.
Syntax:
file.read((char*)&object, sizeof(object));

Example (continued):
Student s2;
ifstream fin("student.dat", ios::binary);
fin.read((char*)&s2, sizeof(s2));
fin.close();
10. Explain command line arguments in C++? Write program to explain the same.
ANS: Command Line Arguments in C++
Definition:
Command line arguments allow users to pass parameters to a program at the time of execution
from the terminal or command prompt.
Main Function Syntax with Command Line Arguments:
int main(int argc, char* argv[])
 argc: (Argument Count) – Number of arguments passed, including the program name.
 argv[]: (Argument Vector) – Array of character pointers listing all arguments. argv[0] is the
name of the program.
argv[1] to argv[argc-1] are the actual user-supplied arguments.
Use Case:
 Reading file names
 Taking user input at runtime without cin
 Automating batch processing

Example Program: Command Line Arguments


#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
cout << "Number of arguments: " << argc << endl;
for (int i = 0; i < argc; i++) {
cout << "Argument " << i << ": " << argv[i] << endl;
}
return 0;
}
How to Run:
If the compiled executable is prog, run from terminal as:
./prog Hello World 123
Output:
Number of arguments: 4
Argument 0: ./prog
Argument 1: Hello
Argument 2: World
Argument 3: 123

11. Which header file do we use for file handling? Explain the following file handling functions
i) seekg ( ) ii)tellg ( ) iii)seekp ( ) iv) tellp ( )
ANS: file handling is supported by the <fstream> header file.

Header File for File Handling

#include <fstream>
This provides:
 ifstream →�for�input�(reading�from�files)
 ofstream →�for�output�(writing�to�files)
 fstream →�for�both�input�and�output

� File Pointer Manipulation Functions


These functions help navigate within files using get (input) and put (output) pointers.

i) seekg()
 Meaning: Seek Get – Moves the input (get) pointer to a specific location in the file.
 Syntax:
fin.seekg(position);
fin.seekg(offset, direction);
 Directions:
o ios::beg →�beginning�of�file
o ios::cur →�current�position
o ios::end →�end�of�file
 Example:
fin.seekg(0, ios::end); // move to end of file

ii) tellg()
 Meaning: Tell Get – Returns the current position of the get pointer.
 Syntax:
streampos pos = fin.tellg();
 Example:
cout << "Current read position: " << fin.tellg() << endl;

iii) seekp()
 Meaning: Seek Put – Moves the output (put) pointer to a specific location.
 Syntax:
fout.seekp(position);
fout.seekp(offset, direction);
 Example:
fout.seekp(5, ios::beg); // move 5 bytes from beginning

iv) tellp()
 Meaning: Tell Put – Returns the current position of the put pointer.
 Syntax:
streampos pos = fout.tellp();
 Example:
cout << "Current write position: " << fout.tellp() << endl;
UNIT 5

1. Explain fundamentals of exception in C++ with suitable example.


ANS: Exception Handling in C++
Exception Handling in C++ provides a way to handle runtime errors, which allows the program to
continue executing even when an error occurs, instead of terminating abruptly.

Fundamentals of Exception Handling


In C++, exceptions are handled using the following keywords:
 try: Defines a block of code in which exceptions are monitored.
 throw: Used to signal the occurrence of an exception.
 catch: Defines blocks that handle the exceptions thrown.

� Syntax:
try {
// Code that might throw an exception
} catch (exception_type1 e1) {
// Code to handle exception_type1
} catch (exception_type2 e2) {
// Code to handle exception_type2
}
 try block contains the code that might throw an exception.
 throw statement raises an exception when an error occurs.
 catch block handles the exception and provides an alternative action.

Types of Exceptions
1. Standard Exception Types:
o std::exception: Base class for all standard exceptions.
o std::runtime_error: Used for runtime errors.
o std::invalid_argument: Raised when a function receives invalid arguments.
2. User-Defined Exceptions: Custom exceptions can be created for specific needs.

� Example of Exception Handling in C++


Example: Handling Division by Zero Error
#include <iostream>
#include <stdexcept> // for std::invalid_argument
using namespace std;

class DivisionByZeroException : public exception {


public:
const char* what() const noexcept override {
return "Error: Division by zero!";
}
};

double divide(double a, double b) {


if (b == 0) {
throw DivisionByZeroException(); // throw exception if denominator is 0
}
return a / b;
}

int main() {
double num1 = 10, num2 = 0;

try {
cout << "Result: " << divide(num1, num2) << endl; // this will throw exception
} catch (const DivisionByZeroException& e) {
cout << e.what() << endl; // Handle the exception
} catch (const exception& e) {
cout << "Caught a general exception: " << e.what() << endl;
}

return 0;
}

2. Discuss class template with suitable example in C++


ANS:
A class template in C++ allows the creation of a class blueprint to work with any data type. It
enables generic programming where the same code works with any data type by using placeholders
instead of specific data types. Templates are a powerful feature of C++ that promotes reusability and
type safety.

Syntax of Class Template:

template <typename T> // or 'class T'


class ClassName {
public:
T value; // variable of type T
ClassName(T val) : value(val) {}
T getValue() {
return value;
}
void setValue(T val) {
value = val;
}
};

Example of Class Template:


#include <iostream>
using namespace std;

// Class template
template <typename T>
class Box {
private:
T length;
public:
Box(T len) : length(len) {}
// Getter function
T getLength() {
return length;
}

// Setter function
void setLength(T len) {
length = len;
}

// Function to calculate volume of a cube


T calculateVolume() {
return length * length * length;
}
};

int main() {
// Create an object of Box with int type
Box<int> intBox(5);
cout << "Length of intBox: " << intBox.getLength() << endl;
cout << "Volume of intBox: " << intBox.calculateVolume() << endl;

// Create an object of Box with double type


Box<double> doubleBox(5.5);
cout << "Length of doubleBox: " << doubleBox.getLength() << endl;
cout << "Volume of doubleBox: " << doubleBox.calculateVolume() << endl;

return 0;
}

3. Write a program in C++ to demonstrate Divide by Zero exception.


ANS:
#include <iostream>
#include <stdexcept> // for std::invalid_argument

using namespace std;

// Function to perform division


double divide(double numerator, double denominator) {
if (denominator == 0) {
// Throw exception if denominator is zero
throw invalid_argument("Error: Division by zero!");
}
return numerator / denominator;
}

int main() {
double num, denom;

// Input values for division


cout << "Enter numerator: ";
cin >> num;

cout << "Enter denominator: ";


cin >> denom;

try {
// Attempt division
double result = divide(num, denom);
cout << "Result: " << result << endl;
}
catch (const invalid_argument& e) {
// Catch the divide by zero exception
cout << e.what() << endl;
}

return 0;
}

4. What is exception in C++? Explain each keyword to handle exception in C++.


ANS: Exception Handling in C++
Exception handling in C++ provides a way to deal with runtime errors (exceptions) in a structured
manner. Instead of letting the program crash when an error occurs, exceptions allow the program to
handle the error and continue its execution.
C++ uses three main keywords for exception handling:
1. try
2. throw
3. catch
These keywords allow us to define error-handling code that helps in managing exceptional
situations.

Keywords in C++ Exception Handling


1. try:
The try block is used to define a section of code where exceptions might occur. It "tries" to execute
the code and monitors it for any exceptions. If an exception occurs, the control is transferred to the
matching catch block.
 Syntax:
try {
// Code that might throw an exception
}
Example:
try {
int result = divide(10, 0); // This will throw an exception (division by zero)
}

2. throw:
The throw keyword is used to throw an exception when a certain error or unwanted condition is
encountered. When an exception is thrown, the normal flow of the program is interrupted, and
control is passed to the nearest catch block.
 Syntax:
throw exception_object; // You can throw any type of object
 You can throw objects of any type, but typically, exceptions are thrown using std::exception
or its derived classes.
Example:
if (denominator == 0) {
throw std::invalid_argument("Error: Division by zero!");
}

3. catch:
The catch block defines how to handle exceptions that are thrown. It catches the exception object
thrown by the throw statement and executes code to handle the exception. You can have multiple
catch blocks to handle different types of exceptions.
 Syntax:
catch (exception_type e) {
// Handle the exception
}
Example:
try {
// Code that might throw an exception
} catch (const std::invalid_argument& e) {
std::cout << "Caught an exception: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cout << "Caught a general exception: " << e.what() << std::endl;
}

Complete Example of Exception Handling

#include <iostream>
#include <stdexcept> // for std::invalid_argument

using namespace std;

double divide(double numerator, double denominator) {


if (denominator == 0) {
throw std::invalid_argument("Error: Division by zero!"); // Throw an exception
}
return numerator / denominator;
}
int main() {
double num, denom;

cout << "Enter numerator: ";


cin >> num;

cout << "Enter denominator: ";


cin >> denom;

try {
double result = divide(num, denom); // Try to perform division
cout << "Result: " << result << endl;
}
catch (const std::invalid_argument& e) {
// Catch and handle division by zero
cout << "Caught exception: " << e.what() << endl;
}

return 0;
}

� Explanation of Keywords:
1. try:
o Defines a block of code that may throw an exception.
o If an exception occurs in this block, control is transferred to the nearest catch block.
2. throw:
o Used to throw an exception manually when an error or specific condition is
encountered.
o The type of exception (e.g., std::invalid_argument) is specified during the throw.
3. catch:
o Defines how to handle exceptions thrown by the try block.
o The exception object is passed as an argument to the catch block.

Advantages of Exception Handling:


1. Separation of error-handling code from the main logic, making the program more readable
and maintainable.
2. Graceful recovery from errors instead of crashing the program.
3. Type-safe: Ensures only the correct type of exception is caught and handled.

5. What is template function? Explain with suitable example


ANS: Template Function in C++
A template function in C++ is a way to write a generic function that can work with any data type.
Instead of defining separate functions for each type, we can use templates to define a function that
can operate on different data types, making the code more flexible and reusable.
C++ templates allow the programmer to define functions (or classes) where the type of data is
determined at compile-time, not runtime.

Syntax of Template Function:


The syntax for defining a template function is as follows:
template <typename T> // or template <class T>
return_type function_name(parameters) {
// function body
}
 T is the template parameter that acts as a placeholder for the data type.
 typename or class are used to specify that T will be a data type.
 The compiler will automatically replace T with the actual data type when the function is
called.

Example of Template Function:


A simple function template to swap two values.

#include <iostream>
using namespace std;

// Template function to swap two values


template <typename T>
void swapValues(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}

int main() {
int x = 10, y = 20;
cout << "Before Swap: x = " << x << ", y = " << y << endl;
swapValues(x, y); // swapping integers
cout << "After Swap: x = " << x << ", y = " << y << endl;

double m = 1.23, n = 4.56;


cout << "Before Swap: m = " << m << ", n = " << n << endl;
swapValues(m, n); // swapping doubles
cout << "After Swap: m = " << m << ", n = " << n << endl;

return 0;
}

Explanation:
1. template <typename T>:
o This line declares a template, where T is a placeholder for any data type. It tells the
compiler that this function can accept parameters of any type.
2. void swapValues(T& a, T& b):
o This function takes two parameters a and b of type T (generic type).
o The function swaps the values of a and b using a temporary variable temp.
3. In main():
o We call the swapValues function twice: once with int values and once with double
values.
o The function works for both types because the compiler automatically generates the
appropriate version of swapValues based on the type used in each call.

Output:
Before Swap: x = 10, y = 20
After Swap: x = 20, y = 10
Before Swap: m = 1.23, n = 4.56
After Swap: m = 4.56, n = 1.23

6. Write a program to demonstrate user defined exception in C++.


ANS: #include <iostream>
#include <stdexcept> // for std::exception
#include <string>

using namespace std;

// Step 1: Define a user-defined exception class


class NegativeNumberException : public std::exception {
public:
// Step 2: Override the 'what()' function to return a custom message
const char* what() const noexcept override {
return "Negative number error: The input number cannot be negative!";
}
};

// A function that throws the user-defined exception if the input is negative


void checkPositive(int num) {
if (num < 0) {
// Step 3: Throw the custom exception
throw NegativeNumberException();
}
cout << "The number " << num << " is positive." << endl;
}

int main() {
int number;

cout << "Enter a number: ";


cin >> number;

try {
// Step 4: Call the function and catch any exceptions thrown
checkPositive(number);
}
catch (const NegativeNumberException& e) {
// Handle the user-defined exception
cout << "Caught exception: " << e.what() << endl;
}
return 0;
}

7. Write a program to demonstrate overloading function template in C++.


ANS:
#include <iostream>
using namespace std;

// Template function for adding two values (version 1)


template <typename T>
T add(T a, T b) {
return a + b;
}

// Template function for adding three values (version 2)


template <typename T>
T add(T a, T b, T c) {
return a + b + c;
}

int main() {
int x = 5, y = 10, z = 15;
double m = 5.5, n = 10.5, o = 15.5;

// Calling the first version of add() with integers


cout << "Sum of two integers: " << add(x, y) << endl;

// Calling the second version of add() with three integers


cout << "Sum of three integers: " << add(x, y, z) << endl;

// Calling the first version of add() with doubles


cout << "Sum of two doubles: " << add(m, n) << endl;

// Calling the second version of add() with three doubles


cout << "Sum of three doubles: " << add(m, n, o) << endl;

return 0;
}

8. What do you mean by rethrowing exceptions. Write a program for the same.
ANS: Rethrowing exceptions means catching an exception and then throwing it again (i.e.,
propagating the exception further up the call stack). This is done when you want to handle the
exception partially (like logging or cleaning up resources) and then allow another part of the
program to deal with the exception more specifically.
Rethrowing is done using the throw; statement inside a catch block without specifying an exception
object.

Steps for Rethrowing Exceptions:


1. Catch an exception in a catch block.
2. Perform any partial handling (logging, cleaning, etc.).
3. Rethrow the exception using the throw; statement to propagate it further.
'
Program to Demonstrate Rethrowing Exceptions:

#include <iostream>
using namespace std;

// Function that throws an exception


void throwException() {
throw std::runtime_error("An error occurred in throwException()");
}

// Function that catches and rethrows an exception


void handleException() {
try {
throwException();
}
catch (const std::exception& e) {
// Partial handling of the exception (e.g., logging)
cout << "Caught exception in handleException: " << e.what() << endl;

// Rethrow the exception to propagate it further


throw;
}
}

int main() {
try {
handleException();
}
catch (const std::exception& e) {
// Final handling of the exception (e.g., displaying a message)
cout << "Caught exception in main: " << e.what() << endl;
}

return 0;
}
9. What is generic programming? How it is implemented in C++.
ANS: Generic Programming is a programming paradigm that aims to write algorithms and data
structures that can work with any data type. The goal of generic programming is to design functions,
classes, and algorithms that are type-independent and can work for any data type without having to
rewrite the code for each type.
In C++, generic programming is primarily achieved using templates. Templates allow you to write
generic code that can be used with any data type, enabling reusability and flexibility.

Key Concepts of Generic Programming:


1. Templates: Templates in C++ allow you to define functions or classes that work with any
data type. These are the core of generic programming in C++.
o Function Templates: Used to define generic functions.
o Class Templates: Used to define generic classes.
2. Type Safety: Generic programming in C++ ensures type safety by allowing the compiler to
deduce types and check for errors at compile-time.
3. Code Reusability: With generic programming, the same function or class can be reused with
multiple data types, reducing code duplication.

Implementation of Generic Programming in C++:


1. Function Template: A template function can perform operations on any data type.

#include <iostream>
using namespace std;

// Generic function to find the maximum of two values


template <typename T>
T findMax(T a, T b) {
return (a > b) ? a : b;
}

int main() {
int x = 5, y = 10;
double m = 3.14, n = 1.59;

// Using the template function with integers


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

// Using the template function with doubles


cout << "Maximum of " << m << " and " << n << " is: " << findMax(m, n) << endl;

return 0;
}
2. Class Template: A class template allows you to define a generic class that can work with any
type of data.

#include <iostream>
using namespace std;

// Generic class for storing a pair of values


template <typename T1, typename T2>
class Pair {
private:
T1 first;
T2 second;

public:
Pair(T1 f, T2 s) : first(f), second(s) {}

void display() {
cout << "First: " << first << ", Second: " << second << endl;
}
};

int main() {
Pair<int, double> p1(10, 20.5);
p1.display(); // First: 10, Second: 20.5

Pair<string, int> p2("Hello", 42);


p2.display(); // First: Hello, Second: 42

return 0;
}
3. Template Specialization: C++ allows the specialization of templates for specific data types,
which means you can define different implementations for specific types.

#include <iostream>
using namespace std;

// Generic function
template <typename T>
void print(T val) {
cout << "Generic: " << val << endl;
}

// Template specialization for int


template <>
void print<int>(int val) {
cout << "Specialized for int: " << val << endl;
}

int main() {
print(5); // Uses the specialized version for int
print(3.14); // Uses the generic version

return 0;
}

10. Write a program in C++ to demonstrate class type exception handling in C++.
ANS: #include <iostream>
#include <exception> // For standard exception handling
using namespace std;
// Custom Exception class that inherits from std::exception
class MyException : public exception {
private:
string errorMessage;

public:
// Constructor to initialize the error message
MyException(const string& msg) : errorMessage(msg) {}

// Override the what() function to provide the error message


const char* what() const noexcept override {
return errorMessage.c_str();
}
};

// Function that throws an exception if an invalid condition is met


void checkValue(int value) {
if (value < 0) {
throw MyException("Value cannot be negative!");
} else if (value == 0) {
throw MyException("Value cannot be zero!");
}
else {
cout << "Valid value: " << value << endl;
}
}

int main() {
try {
// Test cases
checkValue(-5); // This will throw an exception
checkValue(0); // This will also throw an exception
checkValue(10); // This will pass without exception
}
catch (const MyException& ex) {
// Catch the exception and display the error message
cout << "Caught exception: " << ex.what() << endl;
}

return 0;
}
UNIT 6

1. Write a program to demonstrate a map in C++


ANS: #include <iostream>
#include <map>
using namespace std;

int main() {
// Creating a map of string (key) and int (value)
map<string, int> ageMap;

// Inserting data into the map using insert()


ageMap.insert(make_pair("John", 25));
ageMap.insert(make_pair("Alice", 30));
ageMap.insert(make_pair("Bob", 22));

// Inserting data using the array-style operator []


ageMap["Charlie"] = 28;

// Accessing data using the key


cout << "Age of Alice: " << ageMap["Alice"] << endl;
cout << "Age of Charlie: " << ageMap["Charlie"] << endl;

// Iterating through the map and printing all key-value pairs


cout << "\nList of all key-value pairs in the map:\n";
for (auto it = ageMap.begin(); it != ageMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}

// Checking if a key exists in the map


string searchKey = "John";
if (ageMap.find(searchKey) != ageMap.end()) {
cout << "\nFound " << searchKey << " in the map with age " << ageMap[searchKey] << endl;
} else {
cout << "\n" << searchKey << " not found in the map!" << endl;
}

// Deleting an element from the map


cout << "\nRemoving Alice from the map\n";
ageMap.erase("Alice");

// Checking if the element is deleted


if (ageMap.find("Alice") == ageMap.end()) {
cout << "Alice has been removed from the map!" << endl;
}
return 0;
}

2. Enlist various containers in STL. Explain any one with the help of a program
ANS: STL provides a rich collection of container types that allow you to store and manipulate
collections of data efficiently. The main categories of containers in STL are:
1. Sequence Containers:
o vector: Dynamic array that can grow and shrink in size.
o deque: Double-ended queue, allows fast insertions/removals at both ends.
o list: Doubly-linked list, elements can be inserted or removed from both ends.
o array: Fixed-size array (since C++11).
o forward_list: Singly-linked list (since C++11).
2. Associative Containers:
o set: Stores unique elements in a sorted order.
o map: Stores key-value pairs with unique keys in sorted order.
o multiset: Stores multiple occurrences of elements in a sorted order.
o multimap: Stores key-value pairs with duplicate keys in sorted order.
3. Unordered Associative Containers:
o unordered_set: Stores unique elements with no specific order (hash table-based).
o unordered_map: Stores key-value pairs with unique keys and no specific order (hash
table-based).
o unordered_multiset: Stores multiple occurrences of elements with no specific order.
o unordered_multimap: Stores key-value pairs with duplicate keys and no specific
order.
4. Container Adapters:
o stack: Implements a LIFO (Last In First Out) data structure.
o queue: Implements a FIFO (First In First Out) data structure.
o priority_queue: A container that provides fast access to the largest or smallest
element.

Explanation of vector Container with Program


A vector in C++ is a sequence container that can dynamically grow and shrink in size. It is similar to
an array but offers the advantage of resizing itself automatically when elements are added or
removed.
Key features of vector:
 It supports random access to elements.
 It can dynamically grow or shrink in size.
 It stores elements contiguously in memory, making it cache-friendly.
C++ Program to Demonstrate the vector Container:

#include <iostream>
#include <vector> // Include the vector header file
using namespace std;

int main() {
// Create a vector of integers
vector<int> vec;

// Add elements to the vector using push_back()


vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
vec.push_back(40);
vec.push_back(50);

// Display the elements of the vector using a loop


cout << "Vector elements are: ";
for (int i = 0; i < vec.size(); ++i) {
cout << vec[i] << " "; // Accessing elements using the [] operator
}
cout << endl;

// Display the first and last elements using front() and back()
cout << "First element: " << vec.front() << endl;
cout << "Last element: " << vec.back() << endl;

// Remove an element from the end using pop_back()


vec.pop_back();
cout << "After pop_back(), vector elements are: ";
for (int i = 0; i < vec.size(); ++i) {
cout << vec[i] << " ";
}
cout << endl;

// Insert an element at the beginning of the vector


vec.insert(vec.begin(), 5); // Inserting 5 at the beginning
cout << "After insert, vector elements are: ";
for (int i = 0; i < vec.size(); ++i) {
cout << vec[i] << " ";
}
cout << endl;

return 0;
}

3. What is STL? Enlist and explain various components of STL


ANS: The Standard Template Library (STL) is a powerful set of C++ template classes to manage
collections of data. STL provides a set of algorithms and data structures that allow you to store and
manipulate data efficiently. The library is highly flexible, reusable, and provides generic algorithms
that can work with any data type.
Components of STL:
STL consists of the following main components:
1. Containers:
o Containers are used to store data. They are collections of objects, such as lists,
arrays, and sets. STL provides several container types for different types of data
storage needs.
o Types of containers:
 Sequence Containers: These store data in a linear fashion.
 vector: Dynamic array (can resize itself).
 deque: Double-ended queue (allows fast insertions/removals from
both ends).
 list: Doubly linked list (allows insertions/removals at both ends).
 array: Fixed-size array (available in C++11).
 forward_list: Singly linked list (introduced in C++11).
 Associative Containers: These store data in a sorted order based on keys.
 set: Stores unique elements in sorted order.
 map: Stores key-value pairs, where keys are unique and sorted.
 multiset: Allows duplicate elements, stored in sorted order.
 multimap: Allows duplicate key-value pairs, stored in sorted order.
 Unordered Containers: These use hashing and do not maintain any specific
order.
 unordered_set: Stores unique elements, unordered.
 unordered_map: Stores key-value pairs, unordered.
 unordered_multiset: Allows duplicate elements, unordered.
 unordered_multimap: Allows duplicate key-value pairs, unordered.
 Container Adapters: These provide different interfaces for existing
containers.
 stack: LIFO (Last In First Out) data structure.
 queue: FIFO (First In First Out) data structure.
 priority_queue: A specialized queue where elements are ordered by
priority.
2. Iterators:
o Iterators are used to access and traverse the elements in a container. They act like
pointers and can be used to navigate through the data in containers.
o Types of iterators:
 Input Iterator: Used to read data from a container.
 Output Iterator: Used to write data to a container.
 Forward Iterator: Can read/write data in one direction.
 Bidirectional Iterator: Can traverse in both directions (forward and
backward).
 Random Access Iterator: Allows fast access to any element in the container
(like pointers).
3. Algorithms:
o STL provides a rich set of algorithms that can work on containers. These algorithms
operate on iterators and can be used to manipulate and query data stored in
containers. Examples include searching, sorting, copying, modifying, etc.
o Some common algorithms:
 sort(): Sorts a range of elements.
 find(): Searches for an element in a range.
 reverse(): Reverses a range of elements.
 accumulate(): Computes the sum of elements in a range.
 copy(): Copies a range of elements.
 for_each(): Applies a function to each element in a range.
4. Functors (Function Objects):
o Functors are objects that can be used as functions. They are classes or structs that
overload the operator() to allow instances of the class to be called like functions.
Functors are useful when you want to pass custom behavior to algorithms.
5. Allocators:
o Allocators are responsible for managing memory for containers. They are used to
allocate and deallocate memory for objects stored in containers. The default
allocator in STL works for most cases, but custom allocators can be defined for
special memory management needs.

4. What are the various algorithms available in STL? Explain any one with C++ program
ANS: STL provides a rich collection of algorithms that can be used with containers and iterators.
These algorithms are designed to work with various container types and allow you to manipulate
and process data easily.
Some of the most commonly used algorithms in STL are:
1. Sorting Algorithms:
o sort(): Sorts the elements in a container.
o partial_sort(): Sorts part of a container.
o stable_sort(): Sorts the elements while maintaining the order of equal elements.
2. Searching Algorithms:
o find(): Finds the first occurrence of an element.
o binary_search(): Checks if an element exists in a sorted container.
o lower_bound() / upper_bound(): Finds the first or last position of an element in a
sorted container.
3. Modifying Algorithms:
o reverse(): Reverses the order of elements in a container.
o rotate(): Rotates the elements in a container.
o shuffle(): Randomly shuffles the elements.
o fill(): Fills the entire container with a specific value.
o transform(): Applies a function to modify elements.
4. Numeric Algorithms:
o accumulate(): Computes the sum of elements in a range.
o inner_product(): Computes the inner product of two ranges.
o partial_sum(): Computes the partial sum of elements in a range.
5. Other Useful Algorithms:
o for_each(): Applies a function to every element in the container.
o count(): Counts occurrences of a specific value.
o unique(): Removes duplicate consecutive elements in a sorted container.

Explanation of One Algorithm:


#include <iostream>
#include <vector>
#include <algorithm> // for sort()

using namespace std;

int main() {
// Initialize a vector with unsorted integers
vector<int> v = {40, 10, 30, 20, 50, 60, 5};

// Display the vector before sorting


cout << "Before sorting: ";
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;

// Sort the vector in ascending order


sort(v.begin(), v.end());

// Display the vector after sorting


cout << "After sorting: ";
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;

return 0;
}
11. Write a program to implement map in C++
ANS: #include <iostream>
#include <map> // Include the map header file

using namespace std;

int main() {
// Create a map where keys are strings and values are integers
map<string, int> studentGrades;

// Insert key-value pairs into the map


studentGrades["Alice"] = 90;
studentGrades["Bob"] = 80;
studentGrades["Charlie"] = 85;
studentGrades["David"] = 70;

// Display the map elements


cout << "Student Grades:" << endl;
for (const auto &entry : studentGrades) {
cout << entry.first << ": " << entry.second << endl;
}

// Search for a specific key


string searchName = "Bob";
if (studentGrades.find(searchName) != studentGrades.end()) {
cout << "\n" << searchName << "'s grade is: " << studentGrades[searchName] << endl;
} else {
cout << "\n" << searchName << " is not found in the map." << endl;
}
// Remove a key-value pair
studentGrades.erase("David");

// Display the map after deletion


cout << "\nAfter removing 'David':" << endl;
for (const auto &entry : studentGrades) {
cout << entry.first << ": " << entry.second << endl;
}

return 0;
}

Output:
Student Grades:
Alice: 90
Bob: 80
Charlie: 85
David: 70

Bob's grade is: 80

After removing 'David':


Alice: 90
Bob: 80
Charlie: 85

5. What is a container? What are various types of containers? Explain any two containers in
details.
ANS: A container is a data structure provided by the Standard Template Library (STL) that is used to
store and manage collections of objects. Containers hold objects of the same type and are used to
organize data, manage memory efficiently, and provide easy access to elements.
Containers in C++ are template classes, meaning that they are defined with a type parameter that
can be specified at compile-time.
Types of Containers in C++ STL:
The C++ STL provides several types of containers, each suited for different use cases. Containers can
be categorized into sequential containers, associative containers, and unordered associative
containers.
1. Sequential Containers: These containers store elements in a linear fashion (i.e., in a
sequence). The elements are stored in a specific order.
o vector
o deque
o list
o array
2. Associative Containers: These containers store elements in a way that allows for fast
searching based on keys. The elements are automatically sorted based on their keys.
o set
o map
o multiset
o multimap
3. Unordered Associative Containers: These containers store elements in a hash-table-based
structure for faster average-time complexity when accessing elements.
o unordered_set
o unordered_map
o unordered_multiset
o unordered_multimap
Detailed Explanation of Two Containers
1. Vector (Sequential Container)
A vector is a dynamic array that can change its size during runtime. It is similar to an array, but with
the added ability to resize automatically when needed. Elements in a vector are stored in contiguous
memory locations, making them efficient for random access.
 Key Properties:
o Dynamic resizing: A vector can grow or shrink in size automatically.
o Efficient access: Elements can be accessed using indices, just like arrays.
o Memory management: Vectors are more efficient than arrays when it comes to
memory allocation and resizing.
o Insertion/Deletion: Efficient for insertions and deletions at the end of the vector, but
less efficient for other positions.
 Syntax:

#include <iostream>
#include <vector>

int main() {
std::vector<int> vec; // Create a vector of integers

// Adding elements to the vector


vec.push_back(10);
vec.push_back(20);
vec.push_back(30);

// Accessing elements
std::cout << "First element: " << vec[0] << std::endl;
std::cout << "Second element: " << vec.at(1) << std::endl;

// Iterating through vector


std::cout << "Vector elements: ";
for (int i = 0; i < vec.size(); i++) {
std::cout << vec[i] << " ";
}
std::cout << std::endl;

// Removing the last element


vec.pop_back();
std::cout << "After pop_back, size: " << vec.size() << std::endl;

return 0;
}
 Output:

First element: 10
Second element: 20
Vector elements: 10 20 30
After pop_back, size: 2
2. Map (Associative Container)
A map is an associative container that stores key-value pairs. The keys are unique, and each key is
associated with a value. The elements in a map are stored in sorted order based on the key.
 Key Properties:
o Sorted by keys: The elements are stored in ascending order of the key by default.
o Unique keys: Each key in a map must be unique, and a value can be retrieved based
on its associated key.
o Efficient searching: Maps provide efficient search, insertion, and deletion of key-
value pairs.
 Syntax:

#include <iostream>
#include <map>

int main() {
std::map<int, std::string> studentGrades; // Map with integer keys and string values

// Inserting key-value pairs


studentGrades[1] = "Alice";
studentGrades[2] = "Bob";
studentGrades[3] = "Charlie";

// Accessing elements using the key


std::cout << "Student with ID 1: " << studentGrades[1] << std::endl;
std::cout << "Student with ID 2: " << studentGrades.at(2) << std::endl;

// Iterating through the map


std::cout << "All students:" << std::endl;
for (const auto& pair : studentGrades) {
std::cout << "ID: " << pair.first << ", Name: " << pair.second << std::endl;
}

// Searching for a key


int searchID = 2;
if (studentGrades.find(searchID) != studentGrades.end()) {
std::cout << "Student with ID " << searchID << " is: " << studentGrades[searchID] <<
std::endl;
} else {
std::cout << "Student with ID " << searchID << " not found!" << std::endl;
}

return 0;
}
 Output:
yaml
CopyEdit
Student with ID 1: Alice
Student with ID 2: Bob
All students:
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: Charlie
Student with ID 2 is: Bob

6. What is an iterator? What are the various types of iterators?


ANS: An iterator in C++ is an object that allows you to traverse through the elements of a container
(like a vector, list, set, map, etc.) in a sequential manner, similar to how pointers work with arrays.
Iterators provide a generic and uniform way to access and modify elements of a container.
They are used in many STL (Standard Template Library) algorithms to iterate over the container's
elements.
Types of Iterators in C++:
There are several types of iterators in C++, each with different capabilities. They are classified based
on the operations they support:
1. Input Iterator:
o Description: An input iterator is used to read the elements from a container
sequentially.
o Operations Supported:
 Dereference (*): Access the value pointed to by the iterator.
 Increment (++): Move to the next element.
o Example Use Case: Used when traversing through containers for reading.
o Example: Iterating through a vector to print its elements.
2. Output Iterator:
o Description: An output iterator is used to write elements to a container.
o Operations Supported:
 Dereference (*): Write a value at the position pointed to by the iterator.
 Increment (++): Move to the next element for writing.
o Example Use Case: Used when modifying or adding elements to a container.
3. Forward Iterator:
o Description: A forward iterator can read and write to a container. It can only move
forward, not backward.
o Operations Supported:
 Dereference (*): Read the value pointed to by the iterator.
 Increment (++): Move to the next element.
 Can read and modify elements in containers like list, forward_list, and
vector.
o Example Use Case: Used for containers where only forward movement is required
(e.g., linked lists).
4. Bidirectional Iterator:
o Description: A bidirectional iterator can move both forwards and backwards in a
container.
o Operations Supported:
 Dereference (*): Access the element.
 Increment (++): Move to the next element.
 Decrement (--): Move to the previous element.
o Example Use Case: Used for containers like list, set, map, where backward
movement is also necessary.

7. What is Map? Enlist and explain various functions of map.


ANS: A map is an associative container in C++ that stores key-value pairs, where each key is unique
and maps to a value. It is part of the C++ Standard Template Library (STL) and is implemented as a
balanced binary tree (usually Red-Black Tree). Maps automatically maintain the keys in sorted order,
and each key maps to one value, which can be accessed quickly.
 Key Characteristics:
o Unique Keys: Each key can only appear once in a map.
o Sorted Order: Keys are sorted based on the comparator provided (by default, they
are sorted in ascending order).
o Efficient Access: Average time complexity for accessing, inserting, and deleting
elements is O(log⁡n)O(\log n)O(logn).
Maps in C++ can be defined using std::map, where the elements are stored as pairs (key, value).
Syntax to Declare a Map:

std::map<KeyType, ValueType> map_name;

 Example:
std::map<int, std::string> age_map;
In this example, the map stores keys of type int and values of type std::string.

Various Functions of std::map:


C++ provides several functions to manipulate and access data in a map.
1. insert()
 Description: Inserts a key-value pair into the map. If the key already exists, the pair is not
inserted.
 Syntax:
map.insert(pair<KeyType, ValueType>(key, value));
 Example:
age_map.insert(std::make_pair(1, "Alice"));
age_map.insert({2, "Bob"});
2. find()
 Description: Searches for an element with the specified key. Returns an iterator to the
element if found; otherwise, it returns an iterator to map.end().
 Syntax:
map.find(key);
 Example:
auto it = age_map.find(2);
if (it != age_map.end()) {
std::cout << "Found: " << it->second << std::endl; // Access value using '->'
}
3. erase()
 Description: Removes an element with a specified key from the map. If no key is specified, it
removes the element at the specified iterator.
 Syntax:
map.erase(key); // Erase by key
map.erase(iterator); // Erase by iterator
 Example:
age_map.erase(2); // Removes the pair with key = 2
4. size()
 Description: Returns the number of elements in the map.
 Syntax:
map.size();
 Example:
std::cout << "Size of map: " << age_map.size() << std::endl;
5. empty()
 Description: Checks if the map is empty.
 Syntax:
map.empty();
 Example:
if (age_map.empty()) {
std::cout << "The map is empty!" << std::endl;
}

8. What is a vector? Write a C++ program to explain various functions of vector.


ANS: A vector in C++ is a dynamic array that can grow or shrink in size as needed. It is part of the
Standard Template Library (STL) and provides a way to store and manipulate collections of data.
Vectors automatically resize themselves when elements are added or removed, making them more
flexible than arrays.
 Key Features of Vector:
o Dynamic Size: Vectors can automatically resize themselves as needed.
o Random Access: Elements in a vector can be accessed directly using indices.
o Efficient Operations: Vectors support fast access and insertion of elements at the
end of the container, though inserting or deleting elements at arbitrary positions
can be slower than at the end.
o Stored Contiguously: Vectors store their elements in contiguous memory locations,
allowing efficient access.
Functions of a Vector in C++:
C++ vectors provide a variety of functions to manipulate and access data. Below are the key
functions of a vector:
1. push_back()
 Description: Adds an element to the end of the vector.
 Syntax: vector.push_back(value);
2. pop_back()
 Description: Removes the last element from the vector.
 Syntax: vector.pop_back();
3. size()
 Description: Returns the number of elements in the vector.
 Syntax: vector.size();
Example:
#include <iostream>
#include <vector>

int main() {
// Declare a vector of integers
std::vector<int> numbers;
// Add elements to the vector using push_back
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
numbers.push_back(40);

// Display the vector size


std::cout << "Size of vector: " << numbers.size() << std::endl;

// Access elements using at()


std::cout << "Element at index 1: " << numbers.at(1) << std::endl;

// Display the first and last elements


std::cout << "First element: " << numbers.front() << std::endl;
std::cout << "Last element: " << numbers.back() << std::endl;

// Iterate through the vector


std::cout << "Elements in the vector: ";
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;

// Remove last element using pop_back


numbers.pop_back();

// Display the vector after pop_back


std::cout << "After pop_back, size: " << numbers.size() << std::endl;

// Resize the vector to a smaller size


numbers.resize(2);
std::cout << "After resize, size: " << numbers.size() << std::endl;

// Clear the vector


numbers.clear();
std::cout << "After clear, size: " << numbers.size() << std::endl;

return 0;
}

9. What is the algorithm in STL? Explain sort function with example


ANS: STL (Standard Template Library) provides a collection of generic algorithms that can operate
on containers like vectors, lists, maps, etc. These algorithms provide functionalities such as sorting,
searching, modifying, and other operations that can be applied to the contents of containers.
STL algorithms are template functions, which means they can work with any data type or container
type that meets the requirements of the algorithm.

 Sort Function in STL


The sort() function is a part of the <algorithm> header in C++ and is used to sort the elements in a
container (e.g., vector, array) in ascending order by default. The sorting algorithm used is typically
quick sort or introselect (a hybrid of quicksort and heapsort).

 Syntax of sort()
#include <algorithm>
#include <vector>

sort(begin_iterator, end_iterator);

 Example:
#include <iostream>
#include <vector>
#include <algorithm> // For sort

int main() {
// Vector of integers
std::vector<int> numbers = {10, 30, 50, 20, 40};

// Sorting in ascending order (default behavior)


std::sort(numbers.begin(), numbers.end());

// Displaying the sorted vector


std::cout << "Sorted in ascending order: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;

// Sorting in descending order using a custom comparator


std::sort(numbers.begin(), numbers.end(), std::greater<int>());

// Displaying the sorted vector in descending order


std::cout << "Sorted in descending order: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;

return 0;
}

10. What is a sequential container? List various sequential containers. Compare arrays and
vectors
ANS: a sequential container is a type of container in the Standard Template Library (STL) that stores
elements in a specific order, with each element accessible by its position in the sequence. The
elements in sequential containers are stored contiguously or in a way that maintains their ordering.
These containers allow operations like insertion, deletion, and access to elements in a specific
sequence.
 Types of Sequential Containers in STL
1. vector:
o A dynamic array that allows random access to elements.
o The size of the vector can grow dynamically as elements are added.
o Elements are stored contiguously in memory.
2. deque (Double-Ended Queue):
o A sequence container that allows fast insertions and deletions at both the front and
back of the container.
o Unlike vectors, deques are not stored contiguously in memory. They are
implemented as a series of blocks that can grow in both directions.
3. list:
o A doubly linked list, where each element points to both the previous and the next
element.
o Allows efficient insertion and deletion at both ends but does not support direct
random access.
4. forward_list:
o A singly linked list, where each element points to the next element, but not to the
previous one.
o Allows efficient insertion and deletion at the front but has limited functionality
compared to list.
5. array (since C++11):
o A fixed-size array that is part of the standard library.
o It is a wrapper around a built-in array with added functionality, like size tracking and
support for range-based loops.
6. string:
o A container specifically designed to hold sequences of characters.
o It is essentially a specialized vector of characters.

 Comparison between Arrays and Vectors


Both arrays and vectors are sequential containers in C++, but they have distinct differences in
terms of functionality, flexibility, and use cases. Let's compare them:
Feature Array Vector
Fixed at compile time (static
Size Dynamic size; can grow and shrink at runtime.
size).
Contiguous memory block, but can resize
Memory Allocation Contiguous memory block.
dynamically.
Can dynamically resize (using push_back() and
Resize Cannot resize once defined.
pop_back()).
Constant-time access (O(1)), Constant-time access (O(1)), can grow/shrink
Access
but size cannot be changed. dynamically.
Costly (especially in the More efficient insertions/deletions at the end
Insertions/Deletions middle) as elements need to (O(1)). Insertions in the middle take linear time
be shifted. (O(n)).
Best for a fixed number of Ideal for scenarios where the number of
Use Case
elements. elements is not known in advance.
More memory-efficient when Less memory-efficient because of extra space
Memory Efficiency
size is fixed. allocated for dynamic resizing.
Initialized at runtime. Can be initialized with a
Initialization Initialized at compile-time.
specific size.
Feature Array Vector
Access to Elements Direct access using indices. Direct access using indices or iterators.

11. What is iterator? Write a program in C++ to demonstrate the use iterator.
ANS: An iterator in C++ is an object that allows you to traverse through the elements of a container
(such as a vector, list, map, etc.). It is an abstraction of a pointer that enables accessing and
modifying the elements of a container. Iterators provide a unified way to access elements,
regardless of the underlying container type.
Types of Iterators
There are mainly five types of iterators in C++:
1. Input Iterator: Can be used to read the data in one direction (e.g., from the beginning to the
end).
2. Output Iterator: Can be used to write data in one direction.
3. Forward Iterator: Can be used to read or write data in one direction, but can only move
forward (like a single-pass iterator).
4. Bidirectional Iterator: Can move in both directions (forward and backward).
5. Random Access Iterator: Can move freely in both directions and allows direct access to
elements using the [] operator.

 Program to Demonstrate the Use of an Iterator

#include <iostream>
#include <vector>

int main() {
// Declare and initialize a vector
std::vector<int> numbers = {10, 20, 30, 40, 50};

// Declare an iterator for the vector


std::vector<int>::iterator it;

// Using iterator to traverse and print the vector elements


std::cout << "Elements in the vector: ";
for (it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " "; // Dereferencing the iterator to access the value
}
std::cout << std::endl;

// Modify elements using iterator


for (it = numbers.begin(); it != numbers.end(); ++it) {
*it += 5; // Add 5 to each element
}

// Print the modified vector


std::cout << "Modified vector elements: ";
for (it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " "; // Dereferencing the iterator to access the modified value
}
std::cout << std::endl;

return 0;
}

Output:
Elements in the vector: 10 20 30 40 50
Modified vector elements: 15 25 35 45 55

You might also like