0% found this document useful (0 votes)
16 views26 pages

OOP in C++

The document discusses key concepts in C++ programming, including the distinctions between objects and classes, data abstraction and encapsulation, and inheritance and polymorphism. It also explains the role and types of constructors, operator overloading, and provides a menu-driven program for distance operations using member and friend functions. Additionally, it covers the mechanisms of compile-time and run-time polymorphism, along with the differences between run-time and compile-time binding.

Uploaded by

Arshiyan Sayyad
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)
16 views26 pages

OOP in C++

The document discusses key concepts in C++ programming, including the distinctions between objects and classes, data abstraction and encapsulation, and inheritance and polymorphism. It also explains the role and types of constructors, operator overloading, and provides a menu-driven program for distance operations using member and friend functions. Additionally, it covers the mechanisms of compile-time and run-time polymorphism, along with the differences between run-time and compile-time binding.

Uploaded by

Arshiyan Sayyad
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/ 26

C++

Q1.A)Distinguish between the following terms:-

I)Objects And Classes

Ii)Data abstraction and data encapsulation

iii)Inheritance and Polymorphism

Ans:- I) Objects and Classes


 Classes: A class is a blueprint or prototype from which objects are created. It defines
a set of properties (data members) and methods (functions) that are shared by all
objects of the class. A class is like a template that specifies the attributes and
behaviors an object can have.
Example:
cpp
Copy code
class Car {
public:
string color;
string model;
void drive() {
cout << "Driving the car!" << endl;
}
};
 Objects: An object is an instance of a class. It is created based on the blueprint
provided by the class and has its own specific values for the data members. In simple
terms, objects are individual entities that hold the actual data and use the methods of
the class.
Example:
cpp
Copy code
Car car1; // Object of class Car
car1.color = "Red";
car1.model = "Sedan";
car1.drive(); // Calls the method defined in the class
II) Data Abstraction and Data Encapsulation
 Data Abstraction: Data abstraction refers to hiding the complex implementation
details of an object and only exposing the necessary and relevant parts of the object to
the outside world. This is typically achieved by defining abstract classes and
interfaces, and using methods to interact with the data.
Example:
cpp
Copy code
class Shape {
public:
virtual void draw() = 0; // Abstract method
};
 Data Encapsulation: Data encapsulation involves bundling the data (attributes) and
the methods (functions) that operate on the data into a single unit called a class. It also
involves restricting access to the data by making the attributes private and providing
public methods (getters and setters) to access or modify the data.
Example:
cpp
Copy code
class Car {
private:
string color; // Encapsulated data
public:
void setColor(string c) { color = c; } // Setter method
string getColor() { return color; } // Getter method
};
III) Inheritance and Polymorphism
 Inheritance: Inheritance is a mechanism that allows one class (derived class) to
inherit the properties and behaviors (methods) of another class (base class). This
allows for code reusability and a hierarchical class structure.
Example:
cpp
Copy code
class Animal {
public:
void eat() {
cout << "Eating food" << endl;
}
};

class Dog : public Animal { // Dog inherits from Animal


public:
void bark() {
cout << "Barking" << endl;
}
};
Here, Dog inherits the eat() method from Animal.
 Polymorphism: Polymorphism allows a function or method to behave differently
based on the object that invokes it. There are two types: compile-time polymorphism
(method overloading) and runtime polymorphism (method overriding). Polymorphism
allows a single function to operate on objects of different types.
Example:
cpp
Copy code
class Animal {
public:
virtual void sound() { cout << "Some sound" << endl; }
};

class Dog : public Animal {


public:
void sound() override { cout << "Barking" << endl; }
};

Animal* animal = new Dog();


animal->sound(); // Outputs "Barking" due to runtime polymorphism
B)What is the role of constructor in c++? Explain various types of constructor with example?

Ans:- Role of Constructor in C++


A constructor in C++ is a special member function of a class that is automatically called
when an object of that class is created. The primary role of a constructor is to initialize the
object’s data members and allocate any resources that the object may need during its lifetime.
Constructors help ensure that an object starts in a valid state before any operations are
performed on it.
Types of Constructors in C++
There are three types of constructors in C++:
1. Default Constructor
A default constructor is a constructor that takes no arguments or has default values for
all its parameters. If no constructor is explicitly defined by the programmer, the
compiler provides a default constructor that initializes the object with default values.
Example:
cpp
Copy code
class Car {
public:
string color;
string model;

// Default constructor
Car() {
color = "Unknown";
model = "Unknown";
}

void display() {
cout << "Color: " << color << ", Model: " << model << endl;
}
};

int main() {
Car car1; // Calls the default constructor
car1.display(); // Outputs: Color: Unknown, Model: Unknown
return 0;
}
2. Parameterized Constructor
A parameterized constructor allows you to initialize an object with specific values at
the time of its creation. The constructor takes parameters, and you can pass arguments
to initialize the object with different values.
Example:
cpp
Copy code
class Car {
public:
string color;
string model;

// Parameterized constructor
Car(string c, string m) {
color = c;
model = m;
}

void display() {
cout << "Color: " << color << ", Model: " << model << endl;
}
};

int main() {
Car car1("Red", "Sedan"); // Calls parameterized constructor
car1.display(); // Outputs: Color: Red, Model: Sedan
return 0;
}
3. Copy Constructor
A copy constructor is used to create a new object as a copy of an existing object. It is
called when an object is passed by value, returned by value, or explicitly copied. The
copy constructor ensures that a proper copy is made, especially when the class
involves dynamic memory allocation.
Example:
cpp
Copy code
class Car {
public:
string color;
string model;

// Parameterized constructor
Car(string c, string m) {
color = c;
model = m;
}

// Copy constructor
Car(const Car &other) {
color = other.color;
model = other.model;
}

void display() {
cout << "Color: " << color << ", Model: " << model << endl;
}
};

int main() {
Car car1("Blue", "Coupe"); // Original object
Car car2 = car1; // Calls copy constructor
car2.display(); // Outputs: Color: Blue, Model: Coupe
return 0;
}
4. Dynamic Constructor
A dynamic constructor is used when an object is created dynamically using new and
memory needs to be allocated dynamically. This constructor typically uses pointers
and memory allocation techniques such as new or malloc.
Example:
cpp
Copy code
class Car {
public:
string *color;
string *model;

// Dynamic constructor
Car(string c, string m) {
color = new string(c);
model = new string(m);
}

void display() {
cout << "Color: " << *color << ", Model: " << *model << endl;
}

// Destructor to free dynamically allocated memory


~Car() {
delete color;
delete model;
}
};

int main() {
Car *car1 = new Car("Black", "SUV"); // Dynamically created
object
car1->display(); // Outputs: Color: Black, Model: SUV
delete car1; // Free dynamically allocated memory
return 0;
}

Q2. A)What is operator overloading? Write the rules for operator overloading?

Ans:- Operator Overloading in C++


Operator Overloading in C++ allows you to redefine the way operators work for user-
defined classes. By overloading operators, you can make your class behave like built-in types
in terms of operations. This can improve code readability and make custom classes easier to
use in expressions, like adding two objects or comparing them using operators.
For example, you can overload the + operator to add two objects of a class, or the == operator
to compare them.
Syntax of Operator Overloading
The syntax to overload an operator is:
cpp
Copy code
return_type operator op (parameter_list) {
// implementation
}
Where:
 return_type is the return type of the operator (e.g., int, float, or class type).
 op is the operator being overloaded (e.g., +, -, =, etc.).
 parameter_list is the list of parameters that the operator takes.
Example of Operator Overloading
cpp
Copy code
#include<iostream>
using namespace std;

class Complex {
public:
int real;
int imag;

// Parameterized constructor
Complex(int r, int i) : real(r), imag(i) {}
// Overloading + operator to add two Complex numbers
Complex operator + (const Complex& obj) {
return Complex(real + obj.real, imag + obj.imag);
}

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

int main() {
Complex num1(5, 3), num2(2, 7);
Complex result = num1 + num2; // Using overloaded + operator
result.display(); // Outputs: 7 + 10i
return 0;
}
In the example, the + operator is overloaded to add two complex numbers by defining how
the + operator works for objects of the Complex class.
Rules for Operator Overloading
While operator overloading in C++ provides a lot of flexibility, there are certain rules and
limitations that must be followed when overloading operators:
1. Cannot Overload Certain Operators:
Some operators cannot be overloaded, including:
o :: (Scope resolution operator)
o . (Member access operator)
o .* (Pointer to member operator)
o sizeof (Size operator)
o typeid (Run-time type identification)
2. The Number of Operands Cannot Change:
You cannot change the number of operands the operator works with. For example, the
binary + operator will always take two operands.
3. Cannot Overload Built-in Operators for Primitive Types:
You cannot overload operators for built-in types (e.g., int, char, etc.). Operator
overloading only applies to user-defined types.
4. Must Preserve Operator Semantics:
The overloaded operator should behave similarly to its original semantics to avoid
confusing the programmer. For example, the + operator should not change its
behavior in an unexpected way.
5. Cannot Overload the Assignment Operator (=) with Custom Syntax:
The assignment operator can be overloaded, but it must return a reference to *this
and must follow a specific pattern to properly handle object assignment.
Example:
cpp
Copy code
class MyClass {
public:
int value;
MyClass& operator = (const MyClass& obj) {
if (this == &obj) return *this; // Handle self-assignment
value = obj.value;
return *this;
}
};
6. Friend Function for Certain Operators:
Some operators, like << and >> (stream insertion and extraction operators), are often
implemented as friend functions since they need access to the private or protected
members of a class.
Example:
cpp
Copy code
class MyClass {
private:
int value;
public:
MyClass(int v) : value(v) {}

// Overloading the stream insertion operator


friend ostream& operator<<(ostream& out, const MyClass& obj) {
out << obj.value;
return out;
}
};

B)Write a menu-driven program for addition ,substraction,display result of two distance (given in
meter and centimetre)using member function and friend function?

Ans:- Program:
cpp
Copy code
#include<iostream>
using namespace std;

class Distance {
private:
int meters; // stores distance in meters
int centimeters; // stores distance in centimeters

public:
// Constructor to initialize distance
Distance(int m = 0, int cm = 0) {
meters = m;
centimeters = cm;
}

// Member function to display distance


void display() {
cout << meters << " meters " << centimeters << " centimeters" <<
endl;
}

// Member function to add two distances


Distance add(Distance d) {
int totalCentimeters = centimeters + d.centimeters;
int totalMeters = meters + d.meters;

if (totalCentimeters >= 100) { // Convert to meters if centimeters


are >= 100
totalCentimeters -= 100;
totalMeters++;
}
return Distance(totalMeters, totalCentimeters);
}

// Member function to subtract two distances


Distance subtract(Distance d) {
int totalCentimeters = centimeters - d.centimeters;
int totalMeters = meters - d.meters;

if (totalCentimeters < 0) { // Borrow 1 meter if centimeters are


negative
totalCentimeters += 100;
totalMeters--;
}

return Distance(totalMeters, totalCentimeters);


}

// Friend function to compare two distances


friend void compare(Distance d1, Distance d2);
};

// Friend function to compare two distances


void compare(Distance d1, Distance d2) {
int totalCm1 = d1.meters * 100 + d1.centimeters;
int totalCm2 = d2.meters * 100 + d2.centimeters;

if (totalCm1 > totalCm2) {


cout << "Distance 1 is greater." << endl;
} else if (totalCm1 < totalCm2) {
cout << "Distance 2 is greater." << endl;
} else {
cout << "Both distances are equal." << endl;
}
}

int main() {
int choice, m1, cm1, m2, cm2;

cout << "Enter the first distance (in meters and centimeters):\n";
cout << "Meters: ";
cin >> m1;
cout << "Centimeters: ";
cin >> cm1;

cout << "Enter the second distance (in meters and centimeters):\n";
cout << "Meters: ";
cin >> m2;
cout << "Centimeters: ";
cin >> cm2;

Distance d1(m1, cm1), d2(m2, cm2);

do {
cout << "\nMenu:\n";
cout << "1. Add the two distances\n";
cout << "2. Subtract the two distances\n";
cout << "3. Compare the two distances\n";
cout << "4. Exit\n";
cout << "Enter your choice: ";
cin >> choice;
switch(choice) {
case 1: {
Distance result = d1.add(d2);
cout << "The result of addition is: ";
result.display();
break;
}
case 2: {
Distance result = d1.subtract(d2);
cout << "The result of subtraction is: ";
result.display();
break;
}
case 3: {
compare(d1, d2);
break;
}
case 4:
cout << "Exiting the program.\n";
break;
default:
cout << "Invalid choice. Please try again.\n";
}
} while(choice != 4);

return 0;
}
Sample Output:
vbnet
Copy code
Enter the first distance (in meters and centimeters):
Meters: 5
Centimeters: 80
Enter the second distance (in meters and centimeters):
Meters: 3
Centimeters: 40

Menu:
1. Add the two distances
2. Subtract the two distances
3. Compare the two distances
4. Exit
Enter your choice: 1
The result of addition is: 9 meters 20 centimeters

Menu:
1. Add the two distances
2. Subtract the two distances
3. Compare the two distances
4. Exit
Enter your choice: 2
The result of subtraction is: 2 meters 40 centimeters

Menu:
1. Add the two distances
2. Subtract the two distances
3. Compare the two distances
4. Exit
Enter your choice: 3
Distance 1 is greater.
Menu:
1. Add the two distances
2. Subtract the two distances
3. Compare the two distances
4. Exit
Enter your choice: 4
Exiting the program.

Q3.A)How is polymorphism Achived at a) compile time b)run time? What is the difference between
run time binding and compile time binding?

Ans:- Polymorphism is one of the core concepts in object-oriented programming, allowing


objects of different classes to be treated as objects of a common base class. It enables the
same function or method to behave differently based on the object calling it. In C++,
polymorphism is achieved through compile-time polymorphism (also known as static
polymorphism) and run-time polymorphism (also known as dynamic polymorphism).
A) Compile-Time Polymorphism (Static Polymorphism)
Compile-time polymorphism is achieved using function overloading and operator
overloading. The decision of which function or operator to call is made at compile time,
based on the number or type of arguments passed.
Example of Function Overloading (Compile-time Polymorphism):
cpp
Copy code
#include <iostream>
using namespace std;

class Printer {
public:
void print(int i) {
cout << "Printing integer: " << i << endl;
}

void print(double d) {
cout << "Printing double: " << d << endl;
}

void print(string s) {
cout << "Printing string: " << s << endl;
}
};

int main() {
Printer p;
p.print(10); // Calls print(int)
p.print(10.5); // Calls print(double)
p.print("Hello"); // Calls print(string)

return 0;
}
In the above example:

The print function is overloaded to handle different types of arguments: integer, double,
and string.
 The compiler determines which version of the print function to call at compile time, based
on the arguments passed.
Example of Operator Overloading (Compile-time Polymorphism):
cpp
Copy code
#include <iostream>
using namespace std;

class Complex {
public:
int real, imag;

Complex(int r = 0, int i = 0) : real(r), imag(i) {}

// Overloading the + operator


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

int main() {
Complex c1(5, 3), c2(2, 7);
Complex c3 = c1 + c2; // Uses overloaded + operator
cout << "Result: " << c3.real << " + " << c3.imag << "i" << endl;
return 0;
}
In this case, the + operator is overloaded for the Complex class to perform addition on
complex numbers. The overload is resolved at compile time.
B) Run-Time Polymorphism (Dynamic Polymorphism)
Run-time polymorphism is achieved using inheritance and virtual functions. The function
to be invoked is decided at runtime based on the type of the object pointed to by the base
class pointer or reference.
Example of Run-time Polymorphism Using Virtual Functions:
cpp
Copy code
#include <iostream>
using namespace std;

class Animal {
public:
virtual void sound() { // Virtual function
cout << "Animal makes a sound" << endl;
}
};

class Dog : public Animal {


public:
void sound() override { // Overridden function
cout << "Dog barks" << endl;
}
};

class Cat : public Animal {


public:
void sound() override { // Overridden function
cout << "Cat meows" << endl;
}
};

int main() {
Animal* animal1 = new Dog(); // Animal pointer points to Dog object
Animal* animal2 = new Cat(); // Animal pointer points to Cat object
animal1->sound(); // Outputs: Dog barks
animal2->sound(); // Outputs: Cat meows

delete animal1;
delete animal2;

return 0;
}
In this example:
 sound() is a virtual function in the base class Animal, and it is overridden in the derived
classes Dog and Cat.
 At runtime, the program determines which sound() function to call based on the actual
type of the object (i.e., Dog or Cat) rather than the type of the pointer (Animal*).
 This is called runtime polymorphism because the function to be called is resolved at
runtime.
Difference Between Compile-Time Binding and Run-Time Binding
1. Compile-Time Binding:
o Also known as Static Binding.
o The method or function to be invoked is determined at compile time.
o Achieved through function overloading or operator overloading.
o The decision is made based on the function signature or the type of the object.
o No virtual functions are involved.
o Faster because the compiler resolves function calls during compilation.
Example: Function overloading, operator overloading.
cpp
Copy code
class A {
public:
void show() { cout << "Class A" << endl; }
};

class B : public A {
public:
void show() { cout << "Class B" << endl; }
};

int main() {
A* obj = new B();
obj->show(); // This will call the version of show in class A at
compile time.
}
2. Run-Time Binding:
o Also known as Dynamic Binding.
o The method or function to be invoked is determined at runtime.
o Achieved using virtual functions in base classes and function overriding in derived
classes.
o The decision is made based on the actual object that the base class
pointer/reference is pointing to at runtime.
o Virtual functions are involved.
o Slower than compile-time binding due to the overhead of dynamic dispatch.
Example: Virtual function overriding.
cpp
Copy code
class Base {
public:
virtual void display() { cout << "Base Class Display" << endl; }
};

class Derived : public Base {


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

int main() {
Base* b = new Derived();
b->display(); // Resolves at runtime, calls Derived's display.
}
Key Differences Between Run-time Binding and Compile-time Binding:
Feature Compile-time Binding Run-time Binding
Binding Time At compile time At runtime
Types of Function overloading, Operator
Virtual function, Function overriding
Functions overloading
Slower due to overhead of dynamic
Performance Faster because resolved at compile time
dispatch
Flexibility Less flexible, decisions are fixed More flexible, decisions are dynamic
Use Cases Function/Operator Overloading Inheritance, Virtual Functions

B)Explain Virtual function with suitable example?

Ans:- A virtual function in C++ is a member function in a base class that is declared using
the virtual keyword. It allows derived classes to override the base class function, and it
supports runtime polymorphism. The function to be called is determined at runtime based
on the type of object (not the type of pointer or reference) that is used to invoke the function.
This mechanism is crucial in achieving dynamic polymorphism.
Key Points about Virtual Functions:
1. Virtual Function Declaration: A virtual function is declared in the base class using
the virtual keyword.
2. Function Overriding: Derived classes can override the virtual function to provide
their own implementation.
3. Dynamic Binding: The function that is invoked is determined at runtime, depending
on the type of the object (not the pointer type).
4. Base Class Pointer: Virtual functions are typically invoked through a pointer or
reference to the base class.
5. Pure Virtual Function: A virtual function can be made pure virtual by assigning it
to 0 (making the class abstract).
Syntax:
cpp
Copy code
class Base {
public:
virtual void display() { // Virtual function
cout << "Base class display function" << endl;
}
};
class Derived : public Base {
public:
void display() override { // Overriding virtual function
cout << "Derived class display function" << endl;
}
};
Example of Virtual Function in C++
cpp
Copy code
#include <iostream>
using namespace std;

class Animal {
public:
// Virtual function
virtual void sound() {
cout << "Animal makes a sound" << endl;
}

// Destructor should also be virtual in base class for proper cleanup


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

class Dog : public Animal {


public:
void sound() override { // Overriding the sound function
cout << "Dog barks" << endl;
}

~Dog() {
cout << "Dog destructor" << endl;
}
};

class Cat : public Animal {


public:
void sound() override { // Overriding the sound function
cout << "Cat meows" << endl;
}

~Cat() {
cout << "Cat destructor" << endl;
}
};

int main() {
// Creating objects of derived classes
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();

// Using virtual function for dynamic polymorphism


animal1->sound(); // Calls Dog's sound() due to virtual function
animal2->sound(); // Calls Cat's sound() due to virtual function

// Deleting objects using base class pointer to invoke destructors


correctly
delete animal1;
delete animal2;
return 0;
}
Output:
Copy code
Dog barks
Cat meows
Dog destructor
Animal destructor
Cat destructor
Animal destructor

Q4. A)Enlist Header files in c++ draw and explain stream class hierarchy?

Ans:- Enlisting Header Files in C++


In C++, header files are used to define various functions, classes, and constants, which are
used in programs for I/O operations, memory management, and other tasks. Here’s a list of
commonly used header files in C++:
Standard C++ Header Files:
1. <iostream>: Defines input/output stream objects like cin, cout, cerr, and clog.
o Example: #include <iostream>
2. <fstream>: Provides facilities for file handling. Includes ifstream, ofstream, and
fstream for file input/output operations.
o Example: #include <fstream>
3. <iomanip>: Contains input/output manipulators like setw(), setprecision(),
setfill(), etc.
o Example: #include <iomanip>
4. <string>: Defines the string class and its associated functions for string
manipulation.
o Example: #include <string>
5. <cmath>: Contains mathematical functions like sqrt(), sin(), cos(), etc.
o Example: #include <cmath>
6. <cstdlib>: Provides general purpose functions like memory allocation (malloc()),
process control (exit()), etc.
o Example: #include <cstdlib>
7. <cstring>: Contains functions for manipulating C-style strings.
o Example: #include <cstring>
8. <ctime>: Defines functions for time manipulation.
o Example: #include <ctime>
9. <vector>: Defines the vector container for dynamic arrays.
o Example: #include <vector>
10. <algorithm>: Provides standard algorithms like sort(), find(), etc.
o Example: #include <algorithm>
Stream Class Hierarchy in C++
The Stream Class Hierarchy in C++ refers to the organization of classes related to input and
output operations, including file I/O and console I/O. The classes in the hierarchy are
organized in a way that allows them to support both input and output operations using
different types of streams.
Here's a diagram to illustrate the Stream Class Hierarchy:
Plaintext

Copy code
ios (base class)
/ \
ifstream ofstream
/ \ / \
istream ostream fstream
| | |
iostream iostream
Explanation:
1. ios (Base Class):
o The ios class is the base class for all I/O stream classes. It defines the common
functionalities and properties for both input and output operations.
o It provides basic operations like formatting, error flags, and buffer management.
o The ios class also defines important flags like std::ios::in (for input) and
std::ios::out (for output).
2. istream (Input Stream):
o istream is derived from ios and is responsible for handling input operations (e.g.,
reading from the console or a file).
o It provides functions like operator>> to extract data from the stream.
o cin is an object of the istream class, and it's used to read input from the standard
input (keyboard).
3. ostream (Output Stream):
o ostream is another class derived from ios and is responsible for output operations
(e.g., writing to the console or a file).
o It provides functions like operator<< to insert data into the stream.
o cout is an object of the ostream class, and it's used to write output to the standard
output (screen).
4. fstream (File Stream):
o fstream is derived from both istream and ostream, and it supports both input
and output operations for files.
o It is used for reading from and writing to files.
o It includes functions like open(), close(), and read() for file handling
operations.
o fstream objects can be used for both input and output to files.
5. ifstream (Input File Stream):
o ifstream is a subclass of istream, specifically designed for input operations from
files.
o It allows reading from files using the same syntax as console input (i.e.,
operator>>).
o ifstream objects are typically used to open files for reading.
6. ofstream (Output File Stream):
o ofstream is a subclass of ostream, specifically designed for output operations to
files.
o It allows writing to files using the same syntax as console output (i.e., operator<<).
o ofstream objects are typically used to open files for writing.
Example of Using Stream Classes:
cpp
Copy code
#include <iostream>
#include <fstream>
using namespace std;

int main() {
// Creating an output file stream to write to a file
ofstream outFile("example.txt");

if (outFile.is_open()) {
outFile << "Hello, this is a file write operation!\n";
outFile.close(); // Close the file after writing
} else {
cout << "Unable to open file for writing.\n";
}

// Creating an input file stream to read from the file


ifstream inFile("example.txt");

if (inFile.is_open()) {
string line;
while (getline(inFile, line)) { // Reading file line by line
cout << line << endl;
}
inFile.close(); // Close the file after reading
} else {
cout << "Unable to open file for reading.\n";
}

return 0;
}
Explanation of the Code:
 ofstream is used to open a file for output and write a line of text to the file.
 ifstream is used to open the same file for reading and display the contents on the console.

B)Explain ‘this’ Pointer with simple program example ?

Ans:- this Pointer in C++


In C++, the this pointer is a special pointer that is implicitly passed to every non-static
member function of a class. It points to the current object for which the member function is
being called. The this pointer is automatically provided by the compiler and cannot be
modified.
Key Points about the this Pointer:
1. Pointer to Current Object: It holds the memory address of the current object.
2. Access to Member Variables: It can be used to access the current object’s members.
3. Const Nature: The this pointer is a const pointer to the current object, meaning you
cannot change the address it holds, but you can access its members.
4. Implicit: It is passed automatically to all non-static member functions.
5. Cannot be Used with Static Members: Static members do not have a this pointer
because they are not tied to any particular object instance.
Syntax:
cpp
Copy code
ClassName* this;
 Here, this is a pointer to the object of type ClassName.
Example Program Using this Pointer:
cpp
Copy code
#include <iostream>
using namespace std;

class Box {
public:
int length;

// Constructor to initialize length


Box(int len) {
length = len;
}

// Member function to return the current object's length


int getLength() {
return this->length; // Using 'this' pointer to access length
}

// Function to compare the current object with another object


bool compare(Box &b) {
if (this->length == b.length) {
return true;
} else {
return false;
}
}
};

int main() {
Box box1(10); // Create first Box object
Box box2(20); // Create second Box object

cout << "Length of box1: " << box1.getLength() << endl; // Output: 10
cout << "Length of box2: " << box2.getLength() << endl; // Output: 20

if (box1.compare(box2)) {
cout << "Both boxes have the same length." << endl;
} else {
cout << "The boxes have different lengths." << endl; // This will
be executed
}

return 0;
}
Output:
mathematica
Copy code
Length of box1: 10
Length of box2: 20
The boxes have different lengths.
Explanation of the Code:
1. Class Definition: The class Box has a member variable length and a constructor that
initializes it.
2. Using this Pointer: In the getLength() function, the this pointer is used to refer to
the current object’s length. This is optional here, but demonstrates how the this
pointer can be used to access members.
3. Comparing Objects: The compare() function compares the length of the current
object (this->length) with another Box object (b.length). The this pointer is used
to refer to the current object in the comparison.
4. Output:
o The lengths of box1 and box2 are printed.
o The comparison between box1 and box2 shows that their lengths are different.
Key Points in the Example:
 this->length: In the getLength() and compare() functions, this->length
accesses the length of the current object. This is especially useful when there are
naming conflicts or when you want to clarify that you are referring to the current
object's member variable.
 The this pointer is implicitly passed to member functions like getLength() and
compare(). In this program, the explicit use of this is only for demonstration.
Why Use the this Pointer?
1. Disambiguation: The this pointer can help in situations where there is a naming
conflict between parameters and member variables.
2. Referring to Current Object: It helps refer to the current object explicitly,
particularly useful when implementing chained function calls (e.g., returning the
object itself from a function).
Example with Naming Conflict:
cpp
Copy code
#include <iostream>
using namespace std;

class Box {
public:
int length;

// Constructor with a parameter having the same name as the member


variable
Box(int length) {
this->length = length; // 'this->length' refers to the member,
'length' refers to the parameter
}

void display() {
cout << "Length of the box: " << this->length << endl; // Using
'this' to refer to the member
}
};

int main() {
Box box1(15); // Creating an object with length 15
box1.display(); // Output: Length of the box: 15

return 0;
}
Output:
mathematica
Copy code
Length of the box: 15

Q5.A)What is an exception? How is an exceptions handle in c++ ? What are the advantages of using
exceptions handling mechanism in a program?

Ans:- What is an Exception in C++?


An exception in C++ is an event that disrupts the normal flow of a program. It is an error or
unexpected behavior that occurs during program execution, typically caused by issues like
invalid user input, file handling errors, memory allocation failures, or division by zero. When
an exception occurs, the program’s normal execution is halted, and control is transferred to a
special block of code that handles the error, allowing the program to continue running instead
of crashing.
Exceptions are handled using exception handling mechanisms, which include the keywords
try, throw, and catch.
Exception Handling in C++
C++ provides a built-in exception handling mechanism that allows you to catch and handle
runtime errors effectively. This mechanism involves three main components:
1. try block: The code that might throw an exception is enclosed in a try block. This
block is where you anticipate the possibility of an exception occurring.
2. throw keyword: When an exception occurs, the throw keyword is used to "throw" an
exception. This transfers control to the nearest matching catch block.
3. catch block: The catch block is used to handle exceptions thrown by the try block.
It can catch specific types of exceptions and execute corresponding code to manage
the error.
Syntax:
cpp
Copy code
try {
// Code that may throw an exception
// Example: Division by zero, invalid file access
throw exceptionType;
}
catch (exceptionType1 &e) {
// Handle exception of type exceptionType1
}
catch (exceptionType2 &e) {
// Handle exception of type exceptionType2
}
catch (...) {
// Handle any exception if no specific type matches
}
Example Program with Exception Handling in C++:
cpp
Copy code
#include <iostream>
#include <stdexcept> // For standard exception types
using namespace std;

class DivideByZeroException : public exception {


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

double divide(int a, int b) {


if (b == 0) {
throw DivideByZeroException(); // Throw custom exception
}
return static_cast<double>(a) / b;
}

int main() {
int x = 10, y = 0;
try {
cout << "Result: " << divide(x, y) << endl; // This will throw an
exception
}
catch (DivideByZeroException &e) {
cout << e.what() << endl; // Catch and handle divide by zero
exception
}
catch (exception &e) {
cout << "Exception: " << e.what() << endl; // Catch other types of
exceptions
}
return 0;
}
Output:
vbnet
Copy code
Error: Division by zero!
Explanation of the Program:
1. DivideByZeroException Class: This is a custom exception class derived from
std::exception. It overrides the what() function to return a custom error message.
2. divide Function: This function attempts to divide two integers. If the divisor b is
zero, it throws a DivideByZeroException.
3. try Block: In the main function, the try block calls divide(x, y). Since y is zero,
an exception is thrown.
4. catch Block: The catch block catches the thrown DivideByZeroException and
displays the error message using the what() function.
Advantages of Using Exception Handling Mechanism in C++:
1. Separation of Error-Handling Code from Regular Code:
o Exception handling allows you to separate normal logic from error-handling
code. This makes the program cleaner, easier to read, and more maintainable.
You don’t need to clutter your main code with error checks at every step.
2. Automatic Cleanup:
o When an exception is thrown, the runtime system performs automatic
cleanup of local objects. This ensures that any resources (like dynamically
allocated memory or file handles) are properly cleaned up, preventing resource
leaks.
3. Error Propagation:
o Exceptions propagate up the call stack until they are caught by a suitable
catch block. This means you don’t have to handle every error immediately,
and you can let higher-level code handle errors. This is particularly useful in
complex programs with nested function calls.
4. Catching Specific Errors:
o The ability to define and catch specific types of exceptions allows for precise
handling of different errors. You can catch different types of exceptions in
different catch blocks and apply appropriate solutions to each situation (e.g.,
handle division by zero differently from file not found errors).
5. Improved Program Stability:
o Exception handling increases the robustness of the program. Instead of the
program crashing on encountering an error, the exception handling mechanism
can ensure that the program continues to run smoothly or shuts down
gracefully.
6. Better Debugging and Maintenance:
o With exception handling, it is easier to debug and maintain a program because
you can define clear error messages and isolate errors in the code. The use of
try, throw, and catch provides a structured way of identifying and resolving
problems in a program.

B)Write a program in c++ by using swap () function from the functional template?

Ans:- A function template in C++ allows you to write generic functions that can work with
any data type. The swap() function is commonly used to exchange the values of two
variables. Using function templates, we can create a swap() function that works with any
data type, including integers, floats, or custom objects.
Here is an example program using a swap() function with a function template:
Code:
cpp
Copy code
#include <iostream>
using namespace std;

// Function template for swap


template <typename T>
void swap(T &a, T &b) {
T temp = a; // Store the value of a in a temporary variable
a = b; // Assign the value of b to a
b = temp; // Assign the temporary value (original a) to b
}

int main() {
// Test swap with integers
int x = 5, y = 10;
cout << "Before swap (int): x = " << x << ", y = " << y << endl;
swap(x, y); // Call swap for integers
cout << "After swap (int): x = " << x << ", y = " << y << endl;

// Test swap with floating point numbers


double m = 3.14, n = 2.71;
cout << "\nBefore swap (double): m = " << m << ", n = " << n << endl;
swap(m, n); // Call swap for doubles
cout << "After swap (double): m = " << m << ", n = " << n << endl;

// Test swap with strings


string str1 = "Hello", str2 = "World";
cout << "\nBefore swap (string): str1 = " << str1 << ", str2 = " <<
str2 << endl;
swap(str1, str2); // Call swap for strings
cout << "After swap (string): str1 = " << str1 << ", str2 = " << str2
<< endl;

return 0;
}
Output:
csharp
Copy code
Before swap (int): x = 5, y = 10
After swap (int): x = 10, y = 5

Before swap (double): m = 3.14, n = 2.71


After swap (double): m = 2.71, n = 3.14
Before swap (string): str1 = Hello, str2 = World
After swap (string): str1 = World, str2 = Hello

Q6.A) What Are the components of STL? Explain them.

Ans:- Components of the Standard Template Library (STL) in C++


The Standard Template Library (STL) is a collection of template classes and functions in
C++ that provides general-purpose data structures and algorithms. The primary components
of the STL are:
1. Containers
2. Algorithms
3. Iterators
4. Functors (or Function Objects)
Each of these components plays a crucial role in creating efficient and reusable code. Let's
explain each of them:
1. Containers:
Containers are the objects that store data. They provide the basic storage structure for STL.
C++ provides several types of containers that allow the storage of different types of data in
different ways. Containers can be broadly classified into:
 Sequence Containers: These containers maintain the order of insertion. Elements are
stored in a linear fashion.
o vector: A dynamic array that can grow and shrink in size.
o deque: A double-ended queue, allowing fast insertions/removals from both
ends.
o list: A doubly linked list, allowing fast insertions/removals from both ends.
o array: A fixed-size array (introduced in C++11).
 Associative Containers: These containers maintain a collection of key-value pairs
and automatically organize them for fast searching.
o set: A collection of unique elements sorted by value.
o map: A collection of key-value pairs with unique keys.
o multiset: Similar to set, but allows duplicate values.
o multimap: Similar to map, but allows duplicate keys.
 Unordered Containers: These containers store elements in an unordered way and
provide faster average time complexity for search, insertion, and deletion.
o unordered_set
o unordered_map
o unordered_multiset
o unordered_multimap
Example of using a vector container:
cpp
Copy code
#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> v = {1, 2, 3, 4};
v.push_back(5); // Add an element to the end of the vector
for(int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
return 0;
}
2. Algorithms:
STL algorithms are a set of predefined functions that perform operations on containers, such
as searching, sorting, and manipulating data. These algorithms are designed to be used with
STL containers and iterators.
Some commonly used algorithms in STL include:
 Sorting algorithms: sort(), reverse()
 Searching algorithms: find(), binary_search()
 Modification algorithms: copy(), swap(), replace()
 Non-modifying algorithms: count(), equal(), min_element()
Example using sort() and find() algorithms:
cpp
Copy code
#include <iostream>
#include <vector>
#include <algorithm> // For algorithms like sort and find
using namespace std;

int main() {
vector<int> v = {5, 1, 8, 4, 2};
sort(v.begin(), v.end()); // Sort the vector
for(int i : v) {
cout << i << " ";
}
cout << endl;

auto it = find(v.begin(), v.end(), 4); // Find element 4 in the vector


if (it != v.end()) {
cout << "Element 4 found." << endl;
} else {
cout << "Element 4 not found." << endl;
}
return 0;
}
3. Iterators:
Iterators are used to access elements in containers. They are similar to pointers and can be
used to traverse through containers. STL provides different types of iterators for different
needs:
 Input iterators: Used for reading elements from a container.
 Output iterators: Used for writing elements to a container.
 Forward iterators: Can be used to move forward through the container.
 Bidirectional iterators: Can move forward and backward.
 Random access iterators: Can move both forward and backward and access any
element in constant time (like pointers).
Example using an iterator to access elements of a vector:
cpp
Copy code
#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> v = {1, 2, 3, 4, 5};
vector<int>::iterator it; // Declare an iterator for vector

for (it = v.begin(); it != v.end(); ++it) {


cout << *it << " "; // Dereference the iterator to access the
value
}
return 0;
}
4. Functors (Function Objects):
A functor is an object that can be called as if it were a function. Functors are created by
defining a class that overloads the () operator. They can be passed as arguments to STL
algorithms to define custom behavior.
Functors are often used with algorithms to provide custom comparison functions,
transformations, etc.
Example of a functor to be used with sort():
cpp
Copy code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Functor for comparing two integers


class Compare {
public:
bool operator()(int a, int b) {
return a > b; // Sort in descending order
}
};

int main() {
vector<int> v = {10, 20, 5, 15};
sort(v.begin(), v.end(), Compare()); // Use functor with sort

for(int i : v) {
cout << i << " ";
}
return 0;
}

B) Write The Following short notes?

I) Iterators

ii)Container adaptors

iii)Vector

Ans:- I) Iterators in C++


Iterators in C++ are objects that allow you to traverse through the elements of a container
(such as a vector, list, or map). They act like pointers and provide a way to access container
elements sequentially. Iterators abstract the container structure and provide a uniform way to
access elements without needing to know the details of the container's implementation.
Types of Iterators:
1. Input Iterators: Used for reading data from a container (e.g., istream_iterator).
2. Output Iterators: Used for writing data to a container (e.g., ostream_iterator).
3. Forward Iterators: Can move forward through the container.
4. Bidirectional Iterators: Can move both forward and backward through the container (e.g.,
list).
5. Random Access Iterators: Can access elements randomly and efficiently, similar to pointers
(e.g., vector).
Common Operations with Iterators:
 begin(): Returns an iterator to the first element of the container.
 end(): Returns an iterator to the past-the-end element.
 ++it: Advances the iterator to the next element.
 --it: Moves the iterator to the previous element (for bidirectional iterators).
 *it: Dereferences the iterator to access the element.
II) Container Adaptors in C++
Container adaptors are a type of container that modifies the behavior of the underlying
container in some way. They provide a simplified interface for specific types of data storage
and allow you to access elements in a manner different from the underlying container.
C++ Standard Library defines three main types of container adaptors:
1. Stack: Follows the LIFO (Last-In, First-Out) principle. It only allows access to the
top element.
o Container used: deque or vector.
o Functions: push(), pop(), top(), empty(), size().
2. Queue: Follows the FIFO (First-In, First-Out) principle. It allows access to the front
and back of the queue.
o Container used: deque.
o Functions: enqueue(), dequeue(), front(), back(), empty().
3. Priority Queue: Maintains a collection of elements where the elements are ordered
by priority, not by their order of insertion.
o Container used: vector or deque.
o Functions: push(), pop(), top(), empty(), size().
III) Vector in C++
A vector in C++ is a dynamic array provided by the Standard Template Library (STL).
Unlike traditional arrays, a vector can grow or shrink in size during runtime. It is
implemented as a dynamic array, meaning the elements are stored contiguously in memory.
Key Features of Vectors:
1. Dynamic Size: The size of a vector can be changed at runtime by adding or removing
elements.
2. Efficient Random Access: Vectors provide constant-time random access to elements using
indices (like arrays).
3. Automatic Resizing: Vectors automatically resize when more elements are added beyond its
current capacity.
4. Memory Management: Vectors manage memory dynamically, so you don’t need to worry
about memory allocation or deallocation.
Important Operations:
 push_back(): Adds an element to the end of the vector.
 pop_back(): Removes the last element from the vector.
 size(): Returns the number of elements in the vector.
 capacity(): Returns the total number of elements the vector can hold before needing to
resize.
 at(): Accesses an element at a specific index with bounds checking.

You might also like