OOP Super 30
OOP Super 30
Super 30 Questions
Ans :Using operator overloading in C++, you can specify more than one meaning for an operator in one
scope. The purpose of operator overloading is to provide a special meaning of an operator for a user-defined
data type.
With the help of operator overloading, you can redefine the majority of the C++ operators. You can also use
operator overloading to perform different operations using one operator.
int main() {
TestClasstc;
--tc;
tc.Display();
return 0;
}
Ans :
#include <iostream>
class MyClass {
public:
void printMessage(); // Method declaration
};
void MyClass::printMessage() { // Method definition outside the class
std::cout<< "Hello, World!" <<std::endl;
}
int main() {
MyClass obj;
obj.printMessage(); // Calling the method
return 0;
}
In this example, we have a class called MyClass that declares a method printMessage(). However, instead of
defining the method directly within the class, we define it outside the class using the scope resolution operator
MyClass::.
Outside the class definition, we provide the method's return type (void in this case), followed by the class
name (MyClass::) and the method name (printMessage()). Then, we define the method's implementation
within curly braces {}.
Inside the main() function, we create an object obj of type MyClass and call the printMessage() method using
the object.
Output:
Hello, World!
Q3. What is friend function? What are the merits & demerits of using the friend function?
Ans :Friend Function - A friend function is not a member function but has the full right access to the private
member of the class. The friend keyword is used to make a friend function but the function declaration
should be preceded by the keyword friend. The function is defined anywhere in the program like a normal
function.
Example:
class Sample{
int a,b;
public:
void getdata(){
friend int total(Sample s);}
}
void Sample::getdata(){
a=25;
b=20;
}
int total(Sample s){
return(s.a+s.b);
}
int main(){
Sample obj;
obj.getdata();
count<<"Total="<<total(obj);
return 0;
}
Output:
Total =45
Only built-in operators can be overloaded. If some operators are not present in C++, we cannot
overload them.
The arity of the operators cannot be changed
The precedence of the operators remains same.
The overloaded operator cannot hold the default parameters except function call operator “()”.
We cannot overload operators for built-in data types. At least one user defined data types must be
there.
The assignment “=”, subscript “[]”, function call “()” and arrow operator “->” these operators must
be defined as member functions, not the friend functions.
Q5. Which operators cannot be overloaded? Write steps to overload +operator so that it can add two
complex numbers.
To overload the + operator for adding two complex numbers, you can follow these steps in C++:
void display() {
std::cout<< real << " + " << imaginary << "i" << std::endl;
}
};
int main() {
Complex c1(2.5, 3.7);
Complex c2(1.8, 4.2);
Complex sum = c1 + c2; // Operator + overloaded for Complex numbers
sum.display(); // Output: 4.3 + 7.9i
return 0;
}
Q6. Write down program to overload unary operators? (Any three operators).
Ans: Unary operators are operators that operate on a single operand. The following are three examples of
unary operators that can be overloaded in C++:
1. Overloading the unary minus operator (-) to negate the value of an object:
class MyClass {
public:
int value;
MyClass operator-() {
MyClass result;
result.value = -value;
return result;
}
};
int main() {
MyClass obj;
obj.value = 10;
MyClassnegObj = -obj;
std::cout<<negObj.value; // Output: -10
}
2. Overloading the unary plus operator (+) to return the value of an object:
class MyClass {
public:
int value;
MyClass operator+() {
return *this;
}
};
int main() {
MyClass obj;
obj.value=
MyClassposObj = +obj;
std::cout<<posObj.value; // Output: 10
}
3. Overloading the logical not operator (!) to invert the truth value of an object:
class MyClass {
public:
bool value;
bool operator!() {
return !value;
}
};
int main() {
MyClass obj;
obj.value = true;
bool notObj= !obj;
std::cout<<notObj; // Output: false
}
The `getValue` function takes an object of `MyClass` as a parameter and returns its `value`. In the `main`
function, an object of `MyClass` is created with a value of 10, and the `getValue` function is called with this
object as a parameter. The output is 10, which is the value of the private member `value` of the object.
Here is an example of a C++ program to implement operator overloading for a complex class:
#include <iostream>
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
Complex operator + (const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
Complex operator - (const Complex& other) const {
return Complex(real - other.real, imag - other.imag);
}
Complex operator * (const Complex& other) const {
return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);
}
Complex operator / (const Complex& other) const {
double denominator = other.real * other.real + other.imag * other.imag;
return Complex((real * other.real + imag * other.imag) / denominator, (imag * other.real - real *
other.imag) / denominator);
}
friend std::ostream& operator << (std::ostream&os, const Complex& c) {
os<<c.real<< " + " <<c.imag<< "i";
return os;
}
};
int main() {
Complex c1(3, 4);
Complex c2(2, -1);
std::cout<< "c1 = " << c1 << std::endl;
std::cout<< "c2 = " << c2 << std::endl;
std::cout<< "c1 + c2 = " << c1 + c2 << std::endl;
std::cout<< "c1 - c2 = " << c1 - c2 << std::endl;
std::cout<< "c1 * c2 = " << c1 * c2 << std::endl;
std::cout<< "c1 / c2 = " << c1 / c2 << std::endl;
return 0;
}
Q9. Differentiate friend function with normal function of the class.
Ans:
Q10. Write down a C++ program for copy constructor for string class.
Ans:
#include <iostream>
#include <cstring>
class Person {
private:
char* name;
int age;
public:
// Default constructor
Person() {
name = nullptr;
age = 0;
}
// Constructor with parameters
Person(const char* n, int a) {
name = new char[strlen(n) + 1];
strcpy(name, n);
age = a;
}
// Copy constructor
Person(const Person& p) {
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
age = p.age;
}
// Destructor
~Person() {
delete[] name;
}
// Display function
void display() {
std::cout<< "Name: " << name << std::endl;
std::cout<< "Age: " << age << std::endl;
}
};
int main() {
Person p1("John", 25); // Create object using constructor with parameters
Person p2(p1); // Create object using copy constructor
p1.display();
p2.display();
return 0;
}
Q11. Write down program to overload binary operators? (Any two operators).
Ans: Here is an example program to overload the binary operators '+' and '-' for a class named 'Complex':
#include<iostream>
using namespace std;
class Complex {
private:
int real;
int imag;
public:
Complex() {
real = 0;
imag = 0;
}
Complex(int r, int i) {
real = r;
imag = i;
}
Complex operator+(Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
Complex operator-(Complex const &obj) {
Complex res;
res.real = real - obj.real;
res.imag = imag - obj.imag;
return res;
}
void display() {
cout<< real << " + i" <<imag<<endl;
}
};
int main() {
Complex c1(3, 4), c2(2, 5);
Complex c3 = c1 + c2;
Complex c4 = c1 - c2;
c3.display();
c4.display();
return 0;
}
In this program, the '+' and '-' operators are overloaded for the 'Complex' class. The '+' operator adds the real
and imaginary parts of two complex numbers and returns the result as a new 'Complex' object. The '-'
operator subtracts the real and imaginary parts of two complex numbers and returns the result as a new
'Complex' object.
In the main function, two 'Complex' objects (c1 and c2) are created with different values for their real and
imaginary parts. The '+' operator is used to add these two objects and store the result in another 'Complex'
object (c3). The '-' operator is used to subtract these two objects and store the result in another 'Complex'
object (c4). Finally, the display function is called on both c3 and c4 to print their values.
Unit-IV – Inheritance and Polymorphism
Q1. Explain virtual base class & virtual function with example?
ANS: 1.virtual base class :-
1) The virtual base class is a concept used in multiple inheritances to prevent ambiguity between
multiple instances.
2) Consider the situation where we have one class A . This class A is inherited by two other classes
B and C. Both these class are inherited into another in a new class D as shown in figure below .
3) As we can see from the figure that data members of class A are inherited
twice to class D. One through class B and second through class C. When
any data member of class A is accessed by an object of class D, ambiguity
arises as to which data member would be called. One inherited through B or
the other inherited through C. This confuses compiler and it displays error.
4)To resolve this ambiguity when class A is inherited in both class B and
class C, it is declared as virtual base class by placing a keyword “ virtual”.
6) Program :
#include <iostream>
using namespace std;
class A {
public:
void show()
{
cout << "Hello world \n";
}
};
class B : public A {
};
class C : public A {
};
class D : public B, public C {
};
int main()
{
D object;
object.show();
}
2. virtual function :-
1) A virtual function is a member function that is declared within a base class and is re-defined(overridden)
by a derived class.
2) There is a necessity to use the single pointer to refer to all the objects of the different classes. So, we
create the pointer to the base class that refers to all the derived objects. But, when base class pointer contains
the address of the derived class object, always executes the base class function. This issue can only be resolved
by using the 'virtual' function.
#include <iostream>
using namespace std;
class base {
public:
virtual void print() {
cout << "print base class\n";
}
void show() {
cout << "show base class\n";
}
};
class derived : public base {
public:
void print() {
cout << "print derived class\n";
}
void show() {
cout << "show derived class\n";
}
};
int main()
{
base* bptr;
derived d;
bptr = &d;
bptr->print();
bptr->show();
return 0;
}
Q2. What does inheritance mean in C++? What are different forms of inheritance? Give example of
each.
Ans: 1) The capability of a class to derive properties and characteristics from another class is
called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming.
2)Inheritance is a feature or a process in which, new classes are created from the existing classes.
3) The new class created is called “derived class” or “child class” and the existing class is known as the
“base class” or “parent class”.
4) Syntax:
class <derived_class_name> : <access-specifier> <base_class_name>
{
//body
}
5) Types of Inheritance :
Single Inheritance
Multiple Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Hybrid Inheritance
1) Single Inheritance:
Single inheritance is one of the simplest inheritance among other types of inheritance in C++, in which
the child class is derived only from the single parent class.
Syntax
class base_class_1
{ // class definition };
2) Multiple Inheritance:
The inheritance in which a class can inherit or derive the characteristics of multiple classes, or a derived
class can have over one base class, is known as Multiple Inheritance.
syntax
class base_class_1
{ // class definition};
class base_class_2
3) Multilevel Inheritance:
The inheritance in which a class can be derived from another derived class is known as Multilevel Inheritance.
The data members of each respective base class are accessed by their respective derived classes according to
the specified visibility modes.
Syntax
class class_A
{ // class definition };
{ // class definition};
4) Hierarchical Inheritance:
The inheritance in which a single base class inherits multiple derived classes is known as the Hierarchical
Inheritance. This inheritance has a tree-like structure since every class acts as a base class for one or more
child classes.
Syntax
class class_A
{ // class definition};
{ // class definition};
{ // class definition};
5) Hybrid Inheritance:
single inheritance and hierarchical inheritance at the same time. Such an arrangement is known as the
Hybrid Inheritance.
This is arguably the most complex inheritance among all the types of inheritance in C++. The data members
of the base class will be accessed according to the specified visibility mode.
Syntax
class class_A
class class_B
{ // class definition };
2) Inheritance is a mechanism in which one class acquires the property of another class.
3) Inheritance allows developers to create subclasses that reuse code declared already in a superclass.
4) Avoiding the duplication of common functionality between several classes by building a class
inheritance hierarchy can save developers a considerable amount of time.
5) Similarly, placing common functionality in a single superclass, rather than duplicating the code in
multiple unrelated classes, helps prevent the same errors from appearing in multiple source-code files.
6) If errors occur in the common functionality of the superclass, the software developer needs to modify
only the superclass’s.
7) Reusability: The idea of "reusability" is supported by inheritance; for example, if we want to construct
a new class but an existing class already contains some of the code we need, we can derive our new
class from the old class. We are utilizing the fields and methods of the pre-existing class by doing this
8) It makes code much easier to read and understand as it is used to group similar code in code hierarchies.
9) It is also a big time saver, as, by encouraging code reuse, we do not have to repeat code each time we
are writing classes that arelosely semantically related to the ones already written.
10) Hence , we can say that , inheritance promotes software reuse, saves time during program development
and helps prevent errors.
Q4. What is the ambiguity that arises in multiple inheritance? How it can be overcome. Explain with
example
Ans:
1) In multiple inheritances, when one class is derived from two or more base classes then there may be a
possibility that the base classes have functions with the same name, and the derived class may not have
functions with that name as those of its base classes.
2) If the derived class object needs to access one of the similarly named member functions of the base
classes then it results in ambiguity because the compiler gets confused about which base’s class
member function should be called.
3) To solve this ambiguity scope resolution operator is used denoted by ‘ :: ‘.
4) Syntax:
ObjectName.ClassName::FunctionName();
5) Program:
#include <iosteam>
Using namespace std;
class Parent1
{
public:
void YourFunction( )
{ .... ... .... }
};
class Parent2
{
void YourFunction( )
{ .... ... .... }
};
class child : public Parent1, public Parent2
{ };
int main()
{
child object;
object.YourFunction() // ambiguity Error!
}
6) In this example, derived class Child inherited the two base classes parent1 and parent2 having the
same function name YourFunction( ). When the object of class Child is created and called the function
YourFunction( )then the compiler gets confused that which base class member function should be
called.
4) Syntax:
class <derived_class_name> : <access-specifier> <base_class_name>
{
//body
};
5) Types of Inheritance :
Single Inheritance
Multiple Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Hybrid Inheritance
1) Single Inheritance:
Single inheritance is one of the simplest inheritance among other types of inheritance in C++, in which
the child class is derived only from the single parent class.
Syntax
class base_class_1
{ // class definition };
2) Multiple Inheritance:
The inheritance in which a class can inherit or derive the characteristics of multiple classes, or a derived
class can have over one base class, is known as Multiple Inheritance.
syntax
class base_class_1
{ // class definition};
class base_class_2
3) Multilevel Inheritance:
The inheritance in which a class can be derived from another derived class is known as Multilevel Inheritance.
The data members of each respective base class are accessed by their respective derived classes according to
the specified visibility modes.
Syntax
class class_A
{ // class definition };
{ // class definition};
4) Hierarchical Inheritance:
The inheritance in which a single base class inherits multiple derived classes is known as the Hierarchical
Inheritance. This inheritance has a tree-like structure since every class acts as a base class for one or more
child classes.
Syntax
class class_A
{ // class definition};
{ // class definition};
{ // class definition};
5) Hybrid Inheritance:
Single inheritance and hierarchical inheritance at the same time. Such an arrangement is known as the
Hybrid Inheritance.
This is arguably the most complex inheritance among all the types of inheritance in C++. The data members
of the base class will be accessed according to the specified visibility mode.
Syntax
class class_A
class class_B
{ // class definition };
class Base {
public:
int publicMember;
private:
int privateMember;
protected:
int protectedMember;
};
3)In this example, the `publicMember` of the `Base` class is inherited as a public member of the
`Derived` class. It can be accessed directly using an object of the `Derived` class.
2. Private Inheritance:
1) When a derived class inherits privately from a base class, all members of the base class become
private members of the derived class.
2) Private members are only accessible within the class itself and are not accessible by derived classes
or objects of the derived class. Consequently, private inheritance is mainly used to implement
composition rather than inheritance.
Example:
class Base {
public:
int publicMember;
private:
int privateMember;
protected:
int protectedMember;
};
3)In this case, all members of the `Base` class become private members of the `Derived` class. As a
result, they are not directly accessible within the `Derived` class or through objects of the `Derived`
class.
3. Protected Inheritance:
1) When a derived class inherits protectedly from a base class, all members of the base class become
protected members of the derived class.
2) Protected members are accessible within the class itself and by derived classes, but not by objects of
the derived class or other unrelated classes.
Example:
class Base {
public:
int publicMember;
private:
int privateMember;
protected:
int protectedMember;
};
3)In this example, both the `publicMember` and `protectedMember` of the `Base` class are inherited
as protected members of the `Derived` class.
4) They can be accessed within the `Derived` class and by any derived classes, but not through objects
of the `Derived` class.
The access specifiers in inheritance control the visibility and accessibility of inherited members. Public
inheritance preserves the public access level, private inheritance makes all members private, and protected
inheritance makes all members protected in the derived class.
Q7. Explain containment and inheritance along with examples
Ans:
1) In C++, containment and inheritance are two fundamental concepts of object-oriented programming
that facilitate code reuse and organization.
2) In C++, containment and inheritance are two important concepts used in object-oriented programming
to establish relationships between classes.
1. Containment:
1) Containment, also known as composition or aggregation, refers to the practice of including one class
within another class as a member.
2) It represents a "has-a" relationship between the containing class (often called the "container" or
"parent" class) and the contained class (often called the "contained" or "child" class). The container
class owns the contained class and manages its lifetime.
Example:
class Engine {
// Engine class implementation
};
class Car {
Engine engine; // Engine class contained within the Car class
// Car class implementation
};
3) In the above example, the `Car` class contains an `Engine` object as a member variable. The `Car`
class has a "has-a" relationship with the `Engine` class. The lifetime of the `Engine` object is managed by
the `Car` object.
2. Inheritance:
1) Inheritance is a mechanism in object-oriented programming that allows a class to inherit properties
and behavior from another class.
2) The class that is being inherited from is called the "base" class or "superclass," and the class that
inherits from it is called the "derived" class or "subclass."
3) The derived class extends the functionality of the base class and can add new features or override
existing ones.
Example:
class Shape {
public:
virtual void draw() {
// Common implementation for all shapes
}
};
4) In the above example, the `Shape` class is the base class, and both `Circle` and `Square` are derived
classes. They inherit the `draw()` function from the `Shape` class and provide their own
implementation. The derived classes can extend or override the behavior of the base class as per their
specific needs.
5) Inheritance allows for code reuse, as common properties and behavior can be defined in the base class
and shared among multiple derived classes.
6) It also enables polymorphism, where objects of the derived classes can be treated as objects of the base
class, allowing for more flexible and modular code.
Q8. What is a Virtual function? Explain how to achieve runtime polymorphism
In c++, virtual function (also known as virtual methods) is a member function that is declared within a base
class and is re-defined (overridden) by a derived class. When you refer to a derived class object using a pointer
or a reference to the base class, you can call a virtual function for that object and execute the derived class’s
version of the method.
declared with the virtual keyword. When a derived class inherits from the base class and overrides the virtual
function, the derived class can provide its own implementation of the function. This enables runtime
polymorphism, which means that the appropriate function to be called is determined at runtime based on the
actual type of the object.
Virtual functions ensure that the correct function is called for an object, regardless of the type of
reference (or pointer) used for the function call.
They are mainly used to achieve Runtime polymorphism.
Functions are declared with a virtual keyword in a base class.
The resolving of a function call is done at runtime.
Syntax :
class Base {
public:
virtual void someFunction() {
// Base class implementation
}
};
Runtime polymorphism is achieved only through a pointer (or reference) of the base class type. Also, a base
class pointer can point to the objects of the base class as well as to the objects of the derived class. In the above
code, the base class pointer ‘bptr’ contains the address of object ‘d’ of the derived class.
Late binding (Runtime) is done in accordance with the content of the pointer (i.e. location pointed to by
pointer) and Early binding (Compile-time) is done according to the type of pointer since the print() function
is declared with the virtual keyword so it will be bound at runtime (output is print derived class as the pointer
is pointing to object of derived class) and show() is non-virtual so it will be bound during compile time (output
is show base class as the pointer is of base type).
Slower: The function call takes slightly longer due to the virtual mechanism and makes it more difficult for
the compiler to optimize because it does not know exactly which function is going to be called at compile
time.
Difficult to Debug: In a complex system, virtual functions can make it a little more difficult to figure out
where a function is being called from.
Program :
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base Function" << endl;
}
};
int main() {
Derived derived1;
return 0;
}
Output :
Derived Function
Q9. Explain function overloading and function overriding in detail
Function overloading :
1. Function overloading in C++ allows you to define multiple functions with the same name but
different parameters. Each function can perform a similar operation but on different types or
with different numbers of arguments.
2. The compiler determines which function to call based on the arguments provided during the
function call.
3. Function overloading is useful when you want to provide a single interface for performing
related operations on different types or with different argument combinations. It enhances code
readability and flexibility.
4. We can have two people with the same name but very different lives and personalities.
5. Similarly, we often want our function to perform various operations but still have a common
function name.
6. Function overloading is a feature of object-oriented programming, which allows two or more
functions to be created with the same name but with different arguments (different number of
arguments or different data types of arguments).
To overload functions in C++, follow these guidelines:
1. Define multiple functions with the same name but different parameters in the same scope (class
or namespace).
2. The functions must have different parameter types, different number of parameters, or both.
3. The return type of the functions can be the same or different.
4. The functions should have the same name, as that is what enables overloading.
Syntax:
return_type funcion_name (data_type_1 variable1, data_type_2 variable2) { }
Example :
// Function with the same name and different arguments.
int area(int a) {
// Function with one integer parameter.
}
int area(int a, int b) {
// Function with two integer parameters.
}
double area(double a) {
// Function with one parameter of type double.
}
double area(float a, float b) {
// Function with two parameters of type double.
}
Function overriding :
A function is a block of statements that together performs a specific task by taking some input and
producing a particular output.
Function overriding in C++ is termed as the redefinition of base class function in its derived class
with the same signature i.e. return type and parameters. It falls under the category of Runtime
Polymorphism.
the best Real-life example of this concept is the Constitution of India. India took the political code,
structure, procedures, powers, and duties of government institutions and set out fundamental rights,
directive principles, and the duties of citizens of other countries and implemented them on its own;
making it the biggest constitution in the world.
Another Development real-life example could be the relationship between RBI(The Reserve Bank of
India) and Other state banks like SBI, PNB, ICICI, etc. Where the RBI passes the same regulatory
function and others follow it as it is.
class Parent{
access_modifier:
// overridden function
return_type name_of_the_function(){}
};
access_modifier:
// overriding function
return_type name_of_the_function(){}
};
10. What is polymorphism? Explain with example to achieve run time polymorphism?.
Example :
The “ +” operator in c++ can perform two specific functions at two different scenarios i.e when the
“+” operator is used in numbers, it performs addition.
Run time polymorphism is achieved when the object's method is invoked at the run time instead of
compile time.
It is achieved by method overriding which is also known as dynamic binding or late binding.
// Driver code
int main()
{
Geeks obj1;
value of x is 7
value of x is 9.132
value of x and y is 85, 64.
Q11.Write copy constructor for Employee class, in which objects of string class and Date class
are the data members.
#include <iostream>
int main()
{
//create object of class employee
employee emp1;
employee emp=emp1;
emp.getEmployeeInfo();
emp.printEmployeeInfo();
return 0;
}
The following is an example, which throws a division by zero exception and we catch it
in catch block.
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50; int y = 0; double z = 0;
try {
z = division(x, y);
cout << z << endl;
}
catch (const char* msg)
{
cerr << msg << endl;
}
return 0;
}
Q3. Explain class template and function template with example.
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and
generic functions and thus provides support for generic programming.
Generic programming is a technique where generic types are used as parameters in algorithms so that
they can work for a variety of data types.
Function Templates:
We can define a template for a function. For example, if we have an add() function, we can create
versions of the add function for adding the int, float or double type values.
o Generic functions use the concept of a function template. Generic functions define a set of
operations that can be applied to the various types of data.
o The type of the data that the function will operate on depends on the type of the data passed
as a parameter.
o For example, Quick sorting algorithm is implemented using a generic function, it can be
implemented to an array of integers or array of floats.
o A Generic function is created by using the keyword template. The template defines what
function will do
SYNTAX :
In the above declaration, T is the template argument which is a placeholder for the data type used,
and class is a keyword.
Inside the class body, a member variable var and a member function functionName() are both of type
T.
SYNTAX :
Program :
// C++ program to demonstrate the use of class templates
#include <iostream>
using namespace std;
// Class template
template <class T>
class Number {
private:
// Variable of type T
T num;
public:
Number(T n) : num(n) {} // constructor
T getNum() {
return num;
}
};
int main() {
return 0;
}
OUTPUT :
int Number = 7
double Number = 7.7
Program
#include <iostream>
T result = a+b;
return result;
int main()
int i =2;
int j =3;
float m = 2.3;
float n = 1.2;
cout<<'\n';
return 0;
Output:
Addition of i and j is :5
Addition of m and n is :3.5
Q.4 Explain class template using multiple parameters? Write a program in C++.
Templates are powerful features of C++ which allows us to write generic programs. There are two
ways we can implement templates:
Function Templates
Class Templates
Similar to function templates, we can use class templates to create a single class to work with different
data types.
Class templates come in handy as they can make our code shorter and more manageable.
T is the template argument which is a placeholder for the data type used, and class is a keyword.
Inside the class body, a member variable var and a member function functionName() are both of type
T.
T is the template argument which is a placeholder for the data type used, and class is a keyword.
Inside the class body, a member variable var and a member function functionName() are both of type
T.
While creating templates, it is possible to specify more than one type. We can use more than one
generic data type in a class template. They are declared as a comma-separated list within the template
as below:
SYNTAX :
Program :
#include<iostream>
using namespace std;
// Main Function
int main()
{
// instantiation with float and int type
Test <float, int> test1 (1.23, 123);
test1.show();
test2.show();
return 0;
}
Output :
1.23 and 123
100 and W
Q5. Explain namespace in C++ with example. Or what is namespace? Demonstrate namespace with
example.
Ans :
1) In C++, a namespace is a feature that allows you to group related declarations together and avoid
naming conflicts. It provides a way to organize code elements such as variables, functions, and classes
into distinct logical groups.
2) A namespace is like a container that holds identifiers (names) within it. It provides a scope for those
identifiers, ensuring that they don't collide with names defined in other namespaces or in the global
scope.
// First namespace
namespace Math {
int add(int a, int b) {
return a + b;
}
}
// Second namespace
namespace Utility {
int add(int a, int b) {
return a + b;
}
}
int main() {
int result1 = Math::add(2, 3); // Using the add() function from the Math namespace
int result2 = Utility::add(2, 3); // Using the add() function from the Utility namespace
std::cout << "Result from Math namespace: " << result1 << std::endl;
std::cout << "Result from Utility namespace: " << result2 << std::endl;
return 0;
}
```
In the above example, we define two namespaces: `Math` and `Utility`. Each namespace has its own
`add()` function that performs addition. Inside the `main()` function, we can access the `add()`
functions by using the namespace qualifier (`Math::` and `Utility::`). This way, we can differentiate
between the two functions with the same name.
Output:
```
Result from Math namespace: 5
Result from Utility namespace: 5
```
By using namespaces, we can organize our code and avoid naming conflicts. If we didn't use namespaces and
had two functions named `add()`, the compiler would give an error due to the conflict. However, by placing
them in different namespaces, we can use the same name without ambiguity.
Q6. What is stream? Explain types of streams available in C++.
Ans:
1) In C++, a stream is an abstraction that represents a sequence of characters or bytes that can be read from or
written to. Streams are used for input and output operations in C++ and provide a convenient way to handle
data transfer to and from various sources, such as the console, files, or network connections.
2) C++ defines two types of streams: input streams and output streams. These types are further categorized
into three standard stream classes: `iostream`, `istream`, and `ostream`.
1) **iostream**: The `iostream` class is the base class for input and output streams. It provides
functionality for both reading and writing.
2) **istream**: The `istream` class is used for input operations. It is derived from `iostream` and provides
functions for reading data from streams.
3) **ostream**: The `ostream` class is used for output operations. It is also derived from `iostream` and
provides functions for writing data to streams.
By combining these stream classes, we can perform various input and output operations in C++. Here's an
example that demonstrates the usage of different stream types:
#include <iostream>
#include <fstream>
int main() {
int num;
std::cout << "Output using cout: " << num << std::endl;
std::ofstream file("output.txt");
file.close();
return 0;
```
1) We use the `istream` object `cin` (standard input stream) to read a number from the user.
2) We use the `ostream` object `cout` (standard output stream) to display the entered number on the
console.
3) We create an object of the `ofstream` class to write output to a file named "output.txt". We use the
`<<` operator to write the number to the file.
Output:
Enter a number: 42
You entered: 42
The program prompts the user to enter a number, reads it using `cin`, and then displays it using `cout`. It
also writes the number to a file named "output.txt" using an `ofstream` object.
These stream classes provide a wide range of member functions and operators that allow you to perform
formatting, seek operations, error handling, and more. They offer a flexible and standardized way to handle
input and output in C++.
Q7. What is user defined exception? Write down the scenario where we require user defined
exceptions.
Ans:
1) In C++, a user-defined exception refers to creating custom exception classes that extend the
functionality provided by the built-in exception classes in the C++ Standard Library. User-defined
exceptions allow programmers to define and handle specific types of errors or exceptional situations
that are not adequately covered by the standard exception classes.
2) A scenario where user-defined exceptions are required is when you need to handle specific errors or
exceptional conditions that are unique to your application or domain. Here are a few examples:
3) Application-specific errors: In a complex software application, there may be certain errors or
exceptional situations that are specific to the application's logic or requirements. By defining custom
exception classes, you can encapsulate these errors and handle them in a way that makes sense for your
application. For instance, if you are building a banking application, you might define a custom
exception class called InsufficientFundsException to handle cases where a user tries to withdraw more
money than they have in their account.
4) Domain-specific errors: If you are working on a project that deals with a specific domain or industry,
you may encounter errors or exceptional situations that are unique to that domain. By creating custom
exception classes, you can represent and handle these domain-specific errors effectively. For example,
in a scientific simulation software, you might define a custom exception class called
SimulationErrorException to handle errors related to invalid simulation parameters or unexpected
results.
5) Enhanced error reporting: By creating custom exception classes, you can include additional
information or context-specific data with the exceptions. This can be helpful in providing detailed error
messages or debugging information when exceptions occur. For instance, you might define a custom
exception class called FileReadException that includes the name of the file that failed to be read and
additional details about the error, providing more meaningful error messages to the user.
6) Hierarchical exception handling: With user-defined exceptions, you can create a hierarchy of exception
classes to handle different levels of errors or exceptional conditions. This allows you to catch and
handle exceptions at different levels of granularity. For example, you might define a base custom
exception class called BaseException and derive more specific exception classes such as IOException,
DatabaseException, and NetworkException. This hierarchical structure allows you to catch exceptions
at different levels based on their specificity.
7) By using user-defined exceptions, you can improve the error handling and error reporting capabilities
of your code, making it more robust and maintainable. They provide a way to encapsulate and handle
specific errors or exceptional situations that are not adequately covered by the standard exception
classes.
Unit-VI - Working with Files
Q1. What is file mode? Explain any four modes supported in C++
Ans:
In C++, file mode refers to the specific mode or access rights used when opening a
file. It determines how the file can be accessed and manipulated. The four commonly
used modes supported in C++ are:
1. `std::ios::in`: This mode is used for reading input from a file. When a file is opened in
this mode, you can perform read operations on the file, but writing to the file is not
allowed. This mode is typically used when you want to read data from an existing file.
2. `std::ios::out`: This mode is used for writing output to a file. When a file is opened in
this mode, you can perform write operations, but reading from the file is not allowed. If
the file already exists, its contents will be truncated (erased) when opened in this mode.
If the file does not exist, a new file will be created. This mode is commonly used when
you want to write data to a file, either overwriting its contents or creating a new file.
3. `std::ios::app`: This mode is used for appending data to an existing file. When a file is
opened in this mode, you can write data at the end of the file without overwriting the
existing contents. If the file does not exist, a new file will be created. This mode is useful
when you want to add new data to an existing file without erasing its previous contents.
4. `std::ios::binary`: This mode is used for binary file operations. When a file is opened
in this mode, it is treated as a binary file, allowing you to read or write raw binary data.
This mode is commonly used when working with non-text files, such as images, audio
files, or any file where the content is not human-readable text.
It's worth mentioning that these modes can be combined using the bitwise OR operator
(`|`). For example, if you want to open a file in both input and binary modes, you would
use `std::ios::in | std::ios::binary`.
These file modes provide flexibility and control over how files are accessed and
manipulated in C++. By choosing the appropriate mode, you can ensure that your file
operations align with your specific requirements, whether it's reading, writing,
appending, or dealing with binary data.
Q2.Explain error handling during file operations
Ans:
During file operations, error handling is a crucial aspect to ensure that any
potential errors or exceptions that may occur are appropriately handled. Error handling
allows your program to gracefully handle exceptional situations and provide feedback to
the user or take corrective actions.
Here's a general outline of error handling during file operations:
1. Opening a file:
When you open a file, errors can occur if the file doesn't exist, the file is inaccessible,
or there are permission issues. To handle such errors:
- Check if the file exists before attempting to open it.
- Use try-except blocks to catch specific exceptions like `FileNotFoundError` or
`PermissionError`.
- Provide meaningful error messages or take appropriate actions, such as creating a
new file or requesting the user to provide a valid file name.
2. Reading from a file:
Errors can occur while reading from a file if the file is not readable or there are issues
with the file's format. To handle such errors:
- Wrap the reading operation in a try-except block.
- Catch relevant exceptions like `IOError`, `ValueError`, or `UnicodeDecodeError`.
- Handle the error by providing appropriate feedback to the user, retrying the
operation, or taking any other necessary actions.
3. Writing to a file:
Errors can occur while writing to a file if the file is not writable, the disk is full, or there
are other issues with the file system. To handle such errors:
- Wrap the writing operation in a try-except block.
- Catch exceptions like `IOError`, `PermissionError`, or `OSError`.
- Handle the error by informing the user, taking corrective actions, or retrying the write
operation after resolving the issue.
4. Closing a file:
Errors can occur when closing a file if the file is not open or if there are issues with the
file system. To handle such errors:
- Use try-finally or with statements to ensure the file is properly closed even if an error
occurs.
- Wrap the closing operation in a try-except block to catch any exceptions.
- Handle the error by logging it, displaying an appropriate message, or taking
necessary actions to address the issue.
In addition to these general guidelines, it's important to refer to the specific file handling
library or programming language documentation you are using, as they may provide
additional error handling mechanisms or specific exceptions for file-related operations.
Proper error handling improves the robustness and reliability of your code, making it
more resilient to unexpected situations when working with files.
Q3. What is the difference between opening a file with construction function and open()
function?
In C++, there are two primary ways to open a file: using the constructor function of the
file stream class or using the open() function provided by the file stream class. The main
difference lies in the flexibility and timing of file opening.
Constructor Function:
The constructor function is invoked when creating an instance of the file stream class,
such as std::ifstream for input file streams or std::ofstream for output file streams. The
constructor can take the filename and optional file mode as arguments.
For example:
std::ifstream inputFile("example.txt"); // Opens the file during object creation
The key characteristics of using the constructor function are:
The file is opened automatically during object creation.
The file stream object is initialized with the provided filename and mode.
If the file fails to open, you can check the state of the file stream object using the
is_open() member function.
open() Function:
The open() function is a member function of the file stream class (std::ifstream,
std::ofstream, or std::fstream) that allows you to open a file after creating the file stream
object. Here's an example:
std::ifstream inputFile;
inputFile.open("example.txt"); // Opens the file using the open() function
The main characteristics of using the open() function are:
The file stream object is created first, and then you explicitly call the open() function to
open the file.
You can open different files using the same file stream object by calling open() multiple
times.
The file opening process is decoupled from object creation, providing more flexibility.
You need to check the state of the file stream object using the is_open() member
function after calling open() to verify if the file was successfully opened.
In summary, the primary difference between using the constructor function and the
open() function is the timing of the file opening process. The constructor function opens
the file automatically during object creation, while the open() function allows you to open
the file explicitly after creating the file stream object. The choice between the two
approaches depends on your specific requirements and coding style preferences.
Q4. Write a program using the open ( ), eof ( ) & getline ( ) functions to open & read file
contents line by line.
Ans:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream file;
std::string filename, line;
std::cout << "Enter the filename: ";
std::getline(std::cin, filename);
// Open the file
file.open(filename);
// Check if the file was successfully opened
if (!file) {
std::cerr << "Error opening the file." << std::endl;
return 1;
}
// Read the file line by line until the end
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
// Close the file
file.close();
return 0;
}
Q5. Explain file functions for text file and binary file operations.
Ans:
File functions in programming languages are used to perform various operations on files, including reading
from and writing to files. These operations can be carried out on two types of files: text files and binary files.
Let's explore the file functions for each type:
Text File Operations:
1. Opening a File: The `open()` function is used to open a text file. It takes two parameters: the file name and
the mode (read, write, append, etc.). Example: `file = open("example.txt", "r")`.
2. Reading from a File: The `read()` function is used to read the contents of a text file. It can read the entire
file or a specified number of characters. Example: `content = file.read()`.
3. Writing to a File: The `write()` function is used to write data to a text file. It overwrites the existing content.
Example: `file.write("Hello, world!")`.
4. Appending to a File: The `write()` function can also be used to append data to the end of a text file without
overwriting the existing content. Example: `file.write("New line")`.
5. Closing a File: The `close()` function is used to close an opened text file. It's important to close the file after
performing operations on it. Example: `file.close()`.
Binary File Operations:
1. Opening a File: The `open()` function is also used to open a binary file. However, the mode parameter is
different. To open a file in binary mode, use "rb" for reading or "wb" for writing. Example: `file =
open("example.bin", "rb")`.
2. Reading from a File: The `read()` function is used to read binary data from a file. It can read a specified
number of bytes or the entire file. Example: `data = file.read(1024)`.
3. Writing to a File: The `write()` function is used to write binary data to a file. It can write a specified number
of bytes or the entire content of a variable. Example: `file.write(data)`.
4. Appending to a File: Binary files are usually not appended like text files. Instead, you seek to the end of the
file using the `seek()` function and then write the data. Example: `file.seek(0, 2) # Seek to the end of the file`.
5. Closing a File: The `close()` function is used to close an opened binary file, just like with text files. Example:
`file.close()`.
It's important to handle exceptions and errors when working with files to ensure proper file handling and avoid
potential issues.
Q6. Explain file opening modes in detail.
Ans:
When working with files in programming, you typically need to specify the mode in which you want to open
the file. The file opening mode determines how the file can be accessed and modified. In most programming
languages, there are several common file opening modes available. Let's go through them in detail:
1. *Read Mode (`r`):* This is the default mode for file opening. In read mode, you can only read the contents
of the file. If the file does not exist, an error will be thrown. This mode allows the file pointer to be positioned
at the beginning of the file, and you can move the pointer through the file to read its contents.
2. *Write Mode (`w`):* In write mode, you can modify the contents of the file. If the file does not exist, a new
file will be created. If the file already exists, its previous contents will be deleted and replaced with the new
data you write. If the file is opened in write mode and doesn't exist, a new file will be created. The file pointer
is positioned at the beginning of the file.
3. *Append Mode (`a`):* Append mode allows you to add data to the end of an existing file. If the file does
not exist, a new file will be created. The file pointer is positioned at the end of the file, so any data you write
will be appended to the existing content, preserving the original data.
4. *Binary Mode (`b`):* Binary mode is used when dealing with non-text files, such as images, audio, or
binary data. This mode is often used in conjunction with other modes, such as `"rb"` (read binary) or `"wb"`
(write binary).
5. *Update Mode (`+`):* Update mode allows you to perform both read and write operations on a file. It is
represented by adding a `"+"` to the mode string, such as `"r+"`, `"w+"`, or `"a+"`. In update mode, you can
read, write, or append data to the file. The file pointer is positioned at the beginning of the file, and you can
move it to the desired location for reading or writing.
6. *Exclusive Creation Mode (`x`):* Exclusive creation mode is used when you want to create a new file, but
only if it doesn't already exist. It is represented by adding an `"x"` to the mode string, such as `"wx"` or `"ax"`.
If the file already exists, attempting to open it in exclusive creation mode will result in an error.
Additionally, some programming languages provide additional file opening modes or variations. For example:
- *Text Mode (`t`):* Text mode is the default mode in most programming languages and is used for working
with text files. It allows you to read or write text data. In some languages, text mode is the default and doesn't
need to be specified explicitly.
- *Read/Write Mode (`r+` or `w+`):* Read/write mode allows you to perform both read and write operations
on a file. The file pointer is positioned at the beginning of the file, and you can move it to the desired location
for reading or writing.
- *Binary and Text Mode Combination (`rb+` or `wt+`):* Some languages allow combining binary and text
modes, allowing you to read or write binary data while treating the file as a text file.
It's important to note that the available modes and their behavior can vary slightly depending on the
programming language or platform you are using. Always refer to the documentation or specifications of the
specific language or library you are working with for accurate and detailed information on file opening modes.
Q7. Write a note on file operating modes.
Ans:
Note on File Operating Modes:
When working with files in programming languages, understanding and selecting the appropriate file
operating mode is crucial. The mode parameter determines how the file will be accessed and what operations
can be performed on it. Here are some key points to keep in mind:
1. Read Mode ('r'):
- Used for reading the contents of a file.
- The file must exist; otherwise, an error will occur.
- The file pointer is positioned at the beginning of the file.
- Writing operations are not allowed.
2. Write Mode ('w'):
- Used for writing data to a file.
- If the file already exists, its content will be deleted (truncated).
- The file pointer is positioned at the beginning of the file.
- Reading operations are not allowed.
- If the file doesn't exist, a new file will be created.
3. Append Mode ('a'):
- Used for appending data to the end of a file.
- If the file exists, the file pointer is positioned at the end of the file.
- Writing operations will append data to the existing content.
- If the file doesn't exist, a new file will be created.
- Reading operations are allowed.
4. Read and Write Mode ('r+'):
- Used for both reading and writing operations on a file.
- The file must exist; otherwise, an error will occur.
- The file pointer is positioned at the beginning of the file.
- Both reading and writing operations can be performed.
- Caution should be taken when writing, as it can overwrite existing content.
5. Write and Read Mode ('w+'):
- Used for both reading and writing operations on a file.
- If the file exists, its content will be deleted (truncated).
- The file pointer is positioned at the beginning of the file.
- Both reading and writing operations can be performed.
- If the file doesn't exist, a new file will be created.
6. Append and Read Mode ('a+'):
- Used for both reading and appending operations on a file.
- If the file exists, the file pointer is positioned at the end of the file.
- Both reading and appending operations can be performed.
- If the file doesn't exist, a new file will be created.
Remember to handle exceptions and errors appropriately while working with files, such as file not found,
permission issues, or disk full errors. Proper file handling, including opening, performing operations, and
closing the file, is essential to ensure data integrity and avoid potential issues.
Q8.Write a program using put() to write characters to a file until user enters a dollar sign.
Ans:
Certainly! Here's an example program in C++ that uses `std::ofstream` and `put()` to write characters to a file
until the user enters a dollar sign ('$'):
#include <iostream>
#include <fstream>
int main() {
std::ofstream outputFile("output.txt");
if (!outputFile) {
std::cerr << "Error opening the file." << std::endl;
return 1;
}
char ch;
std::cout << "Enter characters (enter '$' to stop):\n";
while (std::cin.get(ch) && ch != '$') {
outputFile.put(ch);
}
outputFile.close();
std::cout << "Data written to the file." << std::endl;
return 0;
}
In this program, we create an `std::ofstream` object named `outputFile` and open the file "output.txt" for
writing. If there is an error opening the file, an error message is printed, and the program exits.
We then prompt the user to enter characters and read them one by one using `std::cin.get(ch)`. The loop
continues as long as the input is successful and the entered character is not a dollar sign ('$'). Inside the loop,
each character is written to the file using `outputFile.put(ch)`.
Finally, we close the file and print a message indicating that the data has been written to the file.
Make sure to include the necessary headers, `<iostream>` and `<fstream>`, at the beginning of your program.
9).Explain manipulators for file handling in C++?
Ans:
In C++, manipulators are functions or objects that modify the behavior of input/output operations performed
on streams. They are primarily used to control the formatting and presentation of data when reading from or
writing to files.
When it comes to file handling, C++ provides several manipulators that can be used with file streams (e.g.,
ifstream and ofstream) to control various aspects of file I/O operations. Here are some commonly used
manipulators for file handling in C++:
setw(int n): This manipulator sets the field width for the next output operation. It specifies the minimum
number of characters that should be used for the output. For example:
cout << setw(10) << "Hello";
This would output " Hello", with five leading spaces to make the total width equal to 10.
setprecision(int n): This manipulator sets the precision for floating-point values. It determines the number of
digits to be displayed after the decimal point. For example:
cout << setprecision(3) << 3.14159;
This would output "3.14", with three digits after the decimal point.
fixed: This manipulator forces the display of floating-point values in fixed-point notation (i.e., with a fixed
number of digits after the decimal point). For example:
cout << fixed << setprecision(2) << 3.14;
scientific: This manipulator forces the display of floating-point values in scientific notation.
cout << scientific << setprecision(3) << 0.0001;
boolalpha: This manipulator displays boolean values as "true" or "false" instead of numeric representations.
For example:
bool value = true;
cout << boolalpha << value;
This would output "true".
These manipulators can be combined and used in various ways to control the formatting and presentation of
data when reading from or writing to files. They provide flexibility and control over how data is displayed and
interpreted during file I/O operations in C++.
10).What is file pointer? Write a note on file opening and file closing.
Ans:
In C++, a file pointer is a variable that is used to keep track of the current position in a file during input/output
operations. It serves as a reference point for reading or writing data in the file. The file pointer is automatically
managed by the C++ I/O library when working with file streams.Whenworking with files in C++, you typically
need to perform two main operations: file opening and file closing.
1.File Opening:
File opening refers to the process of establishing a connection between a file and a program, allowing the
program to read from or write to the file. In C++, you can open a file using file stream objects such as ifstream
(for reading) or ofstream (for writing).
To open a file, you need to follow these steps:
Include the necessary header file for file stream operations:
code
#include <fstream>
// Declare a file stream object and associate it with the file using its constructor:
Code
ifstream inputFile("filename.txt");
// or
ofstream outputFile("filename.txt");
Here, "filename.txt" is the name of the file you want to open. You can specify the file path if the file is not in
the current working directory.
Check if the file was successfully opened by verifying the state of the file stream object:
if (inputFile.is_open()) {
// File opened successfully
} else {
// Failed to open the file
}
If the file opening is successful, the file stream object is ready to be used for reading or writing data from odue
to various reasons such as the file not existing or insufficient permissions.
2.File Closing:
File closing is the process of terminating the connection between a file and a program, freeing up system
resources associated with the file. It is important to close a file after you have finished reading from or writing
to it to ensure proper resource management.
To close a file in C++, you can call the close() member function on the file stream object:
Syntax:
inputFile.close(); // or outputFile.close();
Closing a file also happens automatically when the file stream object goes out of scope or when the program
terminates. However, it is considered good practice to explicitly close the file once you are done with it,
especially when dealing with a large number of file operations or when you want to ensure immediate release
of resources.
By opening and closing files properly, you can ensure the integrity of your data, prevent resource leaks, and
effectively manage file operations in your C++ programs.
11.Explain stream classes hierarchy for file handling in C++?
Ans:
In C++, the stream classes hierarchy provides a structured way to handle file input/output operations. The
stream classes are organized in a hierarchical manner to provide different levels of functionality and
abstraction. The key classes in the stream classes hierarchy for file handling in C++ are:
1. ios_base: It is the base class for all I/O stream classes. It provides basic functionality common to both
input and output streams, such as managing the state of the stream and handling error flags.
2. basic_ios: This class extends ios_base and provides additional functionality specific to input and
output streams. It manages the formatting and error states of the stream.
3. basic_istream: It is the base class for input streams. It provides the functionality for reading data from
a source, such as a file. Some important derived classes from basic_istream include istream and
ifstream.
4. basic_ostream: It is the base class for output streams. It provides the functionality for writing data to
a destination, such as a file. Some important derived classes from basic_ostream include ostream and
ofstream.
5. basic_iostream: It is the base class for streams that support both input and output operations. It
provides a combination of functionality from basic_istream and basic_ostream. Some important
derived classes from basic_iostream include iostream and fstream.
6. istream: This class extends basic_istream and provides input-related operations. It is used for reading
data from sources such as files. It provides functions like getline(), >> (extraction operator), and get().
7. ostream: This class extends basic_ostream and provides output-related operations. It is used for
writing data to destinations such as files. It provides functions like << (insertion operator) and put().
8. iostream: This class extends basic_iostream and combines both input and output functionality. It is
used when you need to perform both input and output operations on a file. It provides function from
both istream and ostream.
9. ifstream: This class extends istream and is specifically designed for reading data from files. It provides
additional file-specific functionality, such as opening and closing files, in addition to the input
operations inherited from istream.
10. ofstream: This class extends ostream and is specifically designed for writing data to files. It provides
additional file-specific functionality, such as opening and closing files, in addition to the output
operations inherited from ostream.
11. fstream: This class extends iostream and provides support for both input and output operations on
files. It combines the functionalities of ifstream and ofstream, allowing reading from and writing to
files.
By using these classes in the stream classes hierarchy, you can perform various file handling operations in
C++, such as opening files, reading data from files, writing data to files, and closing files, while
maintaining a structured and consistent approach to file input/output operations