OPP file
24343(assignment no 2)
ITMC204:OBJECT ORIENTED PROGRAMMING
Submitted by
NAITIK SHAKYA(24343)
IT, 3rd SEMESTER
Submitted to
Dr.Neha Sharma
SCHOOL OF COMPUTING
INDIAN INSTITUTE OF INFORMATION TECHNOLOGY
UNA,HIMACHAL PRADESH
QUESTION 1:
AIM:
To create a class that assigns a unique serial number to each object,
such that the first object gets number 1, the second 2, and so on.
Discription:
This problem introduces the concept of static data members in C++. A static
variable is shared across all objects of a class, instead of being re-initialized for
each object. Here, we use a static counter to keep track of how many objects
have been created so far. The constructor increments the counter and assigns its
value to each object’s serial number. This ensures that every object gets a
unique number.
Code:
#include <iostream>
#include<string>
class serial{
static int count;
public:
int serialno;
std::string name;
serial(std::string name){
this->name = name;
this->serialno = ++count;
}
void print(){
std::cout<<serialno<<" "<<name<<std::endl;
}
};
int serial::count=0;
int main(){
serial s1("naitik");
s1.print();
serial s2("anshul");
s2.print();
}
Ouput:
Question 2:
AIM:
To simulate a tollbooth that counts cars and the total money collected,
distinguishing between paying and non-paying cars.
DISCRIPTION:
The tollbooth problem demonstrates the use of class member functions and data
encapsulation. The program keeps track of two pieces of data: the total number
of cars (unsigned int) and the total toll collected (double). Two functions update
these values: one for paying cars (adds $0.50 and increments car count) and
another for non-paying cars (only increments car count). A display function
outputs the current totals. The program shows how classes can model real-world
entities with states and behaviors.
CODE:
#include <iostream>
#include <conio.h>
using namespace std;
class TollBooth {
unsigned int totalCars;
double totalCash;
public:
TollBooth() : totalCars(0), totalCash(0.0) {}
void payingCar() {
totalCars++;
totalCash += 0.50;
}
void nopayCar() {
totalCars++;
}
void display() const {
cout << "Total cars: " << totalCars << endl;
cout << "Total cash: $" << totalCash << endl;
}
};
int main() {
TollBooth booth;
char ch;
cout << "Press 'p' for paying car, 'n' for non-paying car, 'Esc' to
exit.\n";
while (true) {
ch = _getch();
if (ch == 27) break;
else if (ch == 'p') booth.payingCar();
else if (ch == 'n') booth.nopayCar();
}
booth.display();
return 0;
}
OUTPUT:
Question 3:
AIM:
To create a class that stores a 2D matrix and implements a function to
compute its transpose.
Discription:
This problem illustrates how arrays can be encapsulated in classes and how
matrix operations can be implemented using member functions. The transpose
of a matrix is obtained by interchanging rows and columns. For example,
element at position (i, j) becomes (j, i) in the transposed matrix. By
implementing this in a class, we learn about class data members (matrix
elements, row count, column count) and methods that operate on them.
Code:
#include <iostream>
using namespace std;
class Matrix {
int mat[10][10];
int rows, cols;
public:
void input() {
cout << "Enter rows and columns: ";
cin >> rows >> cols;
cout << "Enter elements:\n";
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
cin >> mat[i][j];
}
void transpose() {
cout << "Transpose:\n";
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
cout << mat[j][i] << " ";
}
cout << endl;
}
}
};
int main() {
Matrix m;
m.input();
m.transpose();
return 0;
}
Output:
Question:4:
AIM:
To define a class ComplexNumber with functions to add and subtract
two complex numbers.
Discription:
Complex numbers have two components: real and imaginary. Operations on
complex numbers are performed component-wise:
Addition: (a+bi)+(c+di)=(a+c)+(b+d)i(a+bi) + (c+di) = (a+c) +
(b+d)i(a+bi)+(c+di)=(a+c)+(b+d)i
Subtraction: (a+bi)–(c+di)=(a–c)+(b–d)i(a+bi) – (c+di) = (a–c) + (b–
d)i(a+bi)–(c+di)=(a–c)+(b–d)i
This problem demonstrates how user-defined types (classes) can model
mathematical concepts. By defining functions for addition and
subtraction inside the class, we achieve abstraction and make operations
intuitive.
Code:
#include <iostream>
using namespace std;
class Complex {
float real, imag;
public:
Complex(float r=0, float i=0) : real(r), imag(i) {}
Complex add(Complex c) {
return Complex(real + c.real, imag + c.imag);
}
Complex subtract(Complex c) {
return Complex(real - c.real, imag - c.imag);
}
void display() {
cout << real << " + " << imag << "i\n";
}
};
int main() {
Complex c1(3, 4), c2(1, 2);
Complex c3 = c1.add(c2);
Complex c4 = c1.subtract(c2);
cout << "Addition: "; c3.display();
cout << "Subtraction: "; c4.display();
return 0;
}
Output:
Question 5:
AIM:
To create a class Angle that stores geographical coordinates (degrees,
minutes, and direction) and provides input and display functions.
Description:
This problem highlights the use of multiple data members of different types (int,
float, char) in a class. A coordinate like “149°34.8′ W” consists of degrees,
minutes, and a direction (N, S, E, W). The class includes:
A function to input values from the user.
A function to display values in formatted style using the degree symbol.
A three-argument constructor to initialize an object directly.
This problem demonstrates constructors, input/output formatting, and
encapsulation of related data.
Code:
#include <iostream>
using namespace std;
class Angle {
int degrees;
float minutes;
char direction;
public:
Angle(int d=0, float m=0.0, char dir='N')
: degrees(d), minutes(m), direction(dir) {}
void getAngle() {
cout << "Enter degrees, minutes and direction: ";
cin >> degrees >> minutes >> direction;
}
void display() const {
cout << degrees << "\xF8" << minutes << "' " << direction << endl;
}
};
int main() {
Angle a1(149, 34.8, 'W');
a1.display();
Angle a2;
a2.getAngle();
a2.display();
return 0;
}
Output:
Question 6:
AIM:
To model a bank account with member functions to deposit,
withdraw, calculate interest, and transfer money between accounts.
Description:
The BankAccount class represents real-world banking operations. It stores
account number, holder’s name, balance, and interest rate.
Deposit increases balance.
Withdrawal decreases balance if sufficient funds are available.
Interest calculation applies a percentage to increase balance.
Transfer moves money from one account to another.
This exercise shows how classes can encapsulate state and behavior,
implement data validation, and simulate real-life systems.
Code:
#include <iostream>
using namespace std;
class BankAccount {
int accNo;
string name;
double balance;
float interestRate;
public:
BankAccount(int no, string n, double bal, float rate)
: accNo(no), name(n), balance(bal), interestRate(rate) {}
void deposit(double amt) { balance += amt; }
void withdraw(double amt) { if (balance >= amt) balance -= amt; }
void addInterest() { balance += (balance * interestRate / 100); }
void transfer(BankAccount &other, double amt) {
if (balance >= amt) {
balance -= amt;
other.balance += amt;
}
}
void display() {
cout << accNo << " " << name << " Balance: " << balance << endl;
}
};
int main() {
BankAccount a1(101, "Naitik", 5000, 5);
BankAccount a2(102, "Anshul", 3000, 4);
a1.transfer(a2, 1000);
a1.display();
a2.display();
return 0;
}
Output:
Question 7:
AIM:
To design an ATM system that authenticates users with a PIN and
provides services such as withdrawal, deposit, balance inquiry, and
mini-statement.
Description:
This problem combines data security (PIN authentication) and transaction
history tracking. The class stores a PIN, account balance, and a list of
transactions. Before performing any operation, the system asks for the correct
PIN. Every transaction is recorded in the history (deposit, withdrawal, etc.),
which can be displayed as a mini statement. This shows how classes can model
more complex systems and enforce security through access control.
Code:
#include <bits/stdc++.h>
using namespace std;
class ATM {
int pin;
double balance;
vector<string> history;
bool authenticate() const {
cout << "Enter PIN: ";
int p; cin >> p;
return p == pin;
}
static string now() {
time_t t = time(nullptr);
tm *lt = localtime(&t);
char buf[32];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", lt);
return string(buf);
}
void addHistory(const string& line) {
ostringstream os;
os << "[" << now() << "] " << line;
history.push_back(os.str());
}
public:
ATM(int setPin, double opening = 0.0) : pin(setPin), balance(opening) {
addHistory("Account created. Opening balance: " + to_string(balance));
}
void deposit() {
if (!authenticate()) { cout << "Auth failed.\n"; return; }
cout << "Amount to deposit: ";
double amt; cin >> amt;
if (amt <= 0) { cout << "Invalid amount.\n"; return; }
balance += amt;
addHistory("Deposit: +" + to_string(amt) + ", Balance: " +
to_string(balance));
cout << "Deposited. Current balance: " << balance << "\n";
}
void withdraw() {
if (!authenticate()) { cout << "Auth failed.\n"; return; }
cout << "Amount to withdraw: ";
double amt; cin >> amt;
if (amt <= 0) { cout << "Invalid amount.\n"; return; }
if (amt > balance) { cout << "Insufficient funds.\n"; return; }
balance -= amt;
addHistory("Withdraw: -" + to_string(amt) + ", Balance: " +
to_string(balance));
cout << "Withdrawn. Current balance: " << balance << "\n";
}
void checkBalance() const {
if (!authenticate()) { cout << "Auth failed.\n"; return; }
cout << "Current balance: " << balance << "\n";
}
void miniStatement() const {
if (!authenticate()) { cout << "Auth failed.\n"; return; }
cout << "---- Mini Statement (last " << history.size() << ") ----\n";
for (const auto& h : history) cout << h << "\n";
}
};
int main() {
ATM myATM(1234, 1000.00);
while (true) {
cout << "\n1) Deposit 2) Withdraw 3) Balance 4) Mini Statement 5)
Exit\nChoose: ";
int ch; if (!(cin >> ch)) break;
switch (ch) {
case 1: myATM.deposit(); break;
case 2: myATM.withdraw(); break;
case 3: myATM.checkBalance(); break;
case 4: myATM.miniStatement(); break;
case 5: cout << "Goodbye!\n"; return 0;
default: cout << "Invalid choice.\n";
}
}
return 0;
}
Output:
Question 8:
AIM:
To simulate file operations (open/close) using constructors and
destructors, and to demonstrate resource management and object
lifetime in C++
Description:
This problem demonstrates the RAII principle (Resource Acquisition Is
Initialization). The constructor simulates opening a file (allocating resources),
while the destructor simulates closing it (releasing resources). By creating
multiple objects, we see that destructors are automatically called in reverse
order of creation when objects go out of scope. It also compares stack allocation
(automatic destruction at scope end) with dynamic allocation (new/delete),
where explicit deletion is required. This illustrates why constructors and
destructors are important for resource safety.
Code:
#include <iostream>
#include <string>
class FileSession {
static int liveCount;
std::string name;
public:
FileSession(const std::string& fname) : name(fname) {
++liveCount;
std::cout << "Opening file: " << name
<< " (live: " << liveCount << ")\n";
}
~FileSession() {
std::cout << "Closing file: " << name
<< " (before close live: " << liveCount << ")\n";
--liveCount;
}
};
int FileSession::liveCount = 0;
int main() {
std::cout << "=== Stack allocation scope ===\n";
{
FileSession f1("stack_alpha.txt");
FileSession f2("stack_beta.txt");
FileSession f3("stack_gamma.txt");
std::cout << "Inside scope...\n";
}
std::cout << "\n=== Dynamic allocation ===\n";
FileSession* p1 = new FileSession("dyn_one.txt");
FileSession* p2 = new FileSession("dyn_two.txt");
std::cout << "Dynamically allocated...\n";
delete p2;
delete p1;
std::cout << "Done.\n";
return 0;
}
Output:
Question 9:
Aim:
To simulate the creation and deletion of temporary files using
constructors and destructors.
Description:
This problem extends the concept of RAII. Each TempStorage object
represents a temporary file. When the constructor runs, it prints a
message that the file is created; when the destructor runs, it prints that
the file is deleted. Multiple objects created in a function are
automatically destroyed when the function ends. Dynamically created
objects must be explicitly deleted. This example shows how C++
handles automatic cleanup and why explicit memory management is
sometimes necessary.
Code:
#include <bits/stdc++.h>
using namespace std;
class TempStorage {
string name;
public:
TempStorage(const string& n) : name(n) {
cout << "Creating temp file: " << name << "\n";
}
~TempStorage() {
cout << "Deleting temp file: " << name << "\n";
}
};
void makeTemps() {
TempStorage t1("temp_A.tmp");
TempStorage t2("temp_B.tmp");
TempStorage t3("temp_C.tmp");
cout << "Working with temps inside makeTemps()\n";
}
int main() {
cout << "=== Automatic (stack) temps ===\n";
makeTemps();
cout << "\n=== Dynamic temp ===\n";
TempStorage* dyn = new TempStorage("temp_D.tmp");
cout << "Doing some work with dynamic temp...\n";
delete dyn;
cout << "All done.\n";
return 0;
}
Output:
Question:10
Aim:
To create a class that calculates and displays an electricity bill based
on customer name, units consumed, and a tariff system.
Description:
The ElectricityBill class demonstrates how to model billing systems. The
program uses slab-based calculation, where the rate per unit depends on how
many units are consumed. The constructor initializes customer details, a
calculation function computes the bill, and a display function prints a formatted
bill. This problem integrates decision making (if-else conditions), encapsulation
of data, and formatted output to represent a practical application of classes.
Code:
#include <bits/stdc++.h>
using namespace std;
struct Tariff {
double upTo100 = 1.50;
double upTo200 = 2.50;
double upTo500 = 4.00;
double above500 = 6.00;
double fixedCharge = 50.0;
};
class ElectricityBill {
string customer;
int units;
double total;
Tariff tf;
public:
ElectricityBill(string name, int unitsConsumed, Tariff t = Tariff())
: customer(std::move(name)), units(unitsConsumed), total(0.0), tf(t)
{}
void calculate() {
int u = units;
total = tf.fixedCharge;
if (u <= 100) {
total += u * tf.upTo100;
return;
}
total += 100 * tf.upTo100; u -= 100;
if (u <= 100) {
total += u * tf.upTo200;
return;
}
total += 100 * tf.upTo200; u -= 100;
if (u <= 300) {
total += u * tf.upTo500;
return;
}
total += 300 * tf.upTo500; u -= 300;
total += u * tf.above500;
}
void display() const {
cout << "Customer : " << customer << "\n";
cout << "Units : " << units << "\n";
cout << fixed << setprecision(2);
cout << "Total : ₹" << total << "\n";
}
};
int main() {
ElectricityBill b1("Naitik Shakya", 86);
b1.calculate();
b1.display();
ElectricityBill b2("Anshul Verma", 245);
b2.calculate();
b2.display();
ElectricityBill b3("Priya", 612);
b3.calculate();
b3.display();
return 0;
}
Output: