0% found this document useful (0 votes)
8 views18 pages

OOP Final Spring'24 Solution

The document contains a series of questions and answers related to C++ programming concepts, including error types, object-oriented principles, code predictions, and class implementations. It covers topics such as compile-time vs. runtime errors, object-oriented programming principles like encapsulation and polymorphism, and the use of templates and operator overloading. Additionally, it includes code snippets for completing object-oriented scenarios, demonstrating class inheritance, and managing vehicle telemetry data.

Uploaded by

k240807
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)
8 views18 pages

OOP Final Spring'24 Solution

The document contains a series of questions and answers related to C++ programming concepts, including error types, object-oriented principles, code predictions, and class implementations. It covers topics such as compile-time vs. runtime errors, object-oriented programming principles like encapsulation and polymorphism, and the use of templates and operator overloading. Additionally, it includes code snippets for completing object-oriented scenarios, demonstrating class inheritance, and managing vehicle telemetry data.

Uploaded by

k240807
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/ 18

Question : 1

Q1: Write short answers (2-3 lines) for the following questions: [10 minutes, 1*5=5 marks]
a) What is the difference between compile-time error and runtime error? Which types of errors
can be dealt with using exceptions?
Answer: Exceptions can be handled during run-time whereas errors cannot be because
exceptions occur due to some unexpected conditions during run-time whereas about
errors compiler is sure and tells about them during compile-time.
b) Which principle of object-oriented programming suits in the below scenarios?
1. A bank vault with multiple layers of security protecting valuable assets.
Encapsulation
2. A car with different driving modes for different road conditions. Polymorphism
c) Write an advantage of using overloading instead of generics in C++?
Answer: Overloading allows the programmer to write more specific code for each data
type.
d) Can a friend function of Base class access the data members of a derived class? No
e) If class C inherits class B and class B inherits class A, then Class C object can be upcasted
to object of either class A or B? Yes

Question : 2

Q2: Predict the output of the following code snippets. If there are any errors, provide a proper
justification.
Exclude errors related to libraries. [25 minutes, 2*5=10 marks]
A. class Test
{ public: Test() { cout <<"Hello from Test() "; }
} a;
int main()
{ cout <<"Main Started "; }
Hello from Test() Main Started

B. class Test {
public:
Test() { cout << "Constructing an object of Test " << endl; }
~Test() { cout << "Destructing an object of Test " << endl; }
};
int main() {
try {
Test t1;
throw 10;
} catch(int i) { cout << "Caught " << i << endl; } }
Constructing an object of Test
Destructing an object of Test
Caught 10
C. template <typename T>
void fun(const T&x)
{ static int count = 0;
cout << "x = " << x << " count = " << count;
++count;
return;
}
int main()
{
fun<int> (1); cout << endl;
fun<int>(1); cout << endl;
fun<double>(1.1); cout << endl;
}
x = 1 count = 0
x = 1 count = 1
x = 1.1 count = 0

D. int main() {
try {
cout<<"Throwing Block"<<endl;
throw 'x';
}
catch (int e) {
cout <<"Catching Int" << e << endl; }
catch (...) {
cout <<"Catching Default" << endl; }
catch (char e) {
cout <<"Catching Char" << e << endl; }
return 0;}
Error because default catch comes in the end

E. char foo(int i) {
if (i % 3 != 0)
return 't';
throw 'o';
return 'p';
}
int main() {
char c = 'c';
try {
for (int i = 1; ; i++) { c = foo(i); cout << "c" << endl;}
}
catch (char ex) {
cout << c << endl; cout << ex << endl; } }
c
c
t
o
Question 03:
Q3: Complete the C++ code for an Object-Oriented Programming (OOP) scenario. [25 minutes,
5*2=10 marks] A. For the given class, you are required to create a specialized template that
manages computations specifically when both arrays are characters with a size of 10. Overload
the function so that it returns a string containing all elements of arr1 followed by all elements of
arr2.

template <class T, int size> //---- start code completion -----


class QuestionTemplate { template <>
T arr1[size]; class QuestionTemplate <char, 10> {
T arr2[size]; char arr1[10];
public: char arr2[10];
QuestionTemplate() { public:
//assume numbers only for now QuestionTemplate() {
for (int i = 0; i < size; i++){ char c = 'a';
arr1[i] = i; for (int i = 0; i < 10; i++) {
arr2[size - i - 1] = i; arr1[i] = c + i;
} arr2[9 - i] = c + i;
} }
T* add() { }
T* arr = new T[size]; string add() {
for (int i = 0; i < size; i++) string str = "";
arr[i] = arr1[i] + arr2[i]; for (int i = 0; i < 10; i++)
return arr; str += arr1[i];
} for (int i = 0; i < 10; i++)
}; str += arr2[i];

return str;
}
};
//---- finish code completion -----

int main() {
QuestionTemplate <int, 10> qt;
int* res = qt.add();
for (int i = 0; i < 10; i++)
cout << res[i] << endl;
QuestionTemplate <char, 10> ct;
cout << ct.add();
}
B. Complete the given code below in such a way that when we run this code, a similar kind of
output is stored in the file.

outfile.txt :
ID = 1, Name = 0001
ID = 2, Name = 0002

class Test {
int ID;
string name;
static int genID;
public:
//---- start code completion -----
Test() {
ID = ++genID;
name = "000" + to_string(genID);
}
void operator + (string filename) {
ofstream fout(filename, ios::app); //ios::app is required, otherwise one line will exist in the
file
fout << "ID = " << this->ID << ", Name = " << this->name <<endl;

}
//---- finish code completion -----

};

int Test::genID = 0;

int main() {
Test t1, t2;

t1 + "outfile.txt";
t2 + "outfile.txt";
}
Question 04:
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

class TelemetryData {
private:
float fuelConsumption; // liters per hour
float speed; // kilometers per hour
bool engineStatus; // true if running, false otherwise

public:
TelemetryData(float fuelConsumption = 0.0, float speed = 0.0, bool engineStatus = false)
: fuelConsumption(fuelConsumption), speed(speed), engineStatus(engineStatus) {}

void displayTelemetry() const {


cout << "Telemetry Data: \n";
cout << "Fuel Consumption: " << fuelConsumption << " liters/hour\n";
cout << "Speed: " << speed << " km/h\n";
cout << "Engine Status: " << (engineStatus ? "Running" : "Stopped") << "\n";
}
};

class Vehicle {
protected:
char vehicleID[10];
char model[50];
char fuelType[10];
char currentLocation[50];
TelemetryData telemetry;

public:
Vehicle(const char* vehicleID, const char* model, const char* fuelType, const char* currentLocation,
const TelemetryData& telemetry)
: telemetry(telemetry) {
strncpy(this->vehicleID, vehicleID, 10);
strncpy(this->model, model, 50);
strncpy(this->fuelType, fuelType, 10);
strncpy(this->currentLocation, currentLocation, 50);
}

virtual void displayDetails() const {


cout << "Vehicle ID: " << vehicleID << "\n";
cout << "Model: " << model << "\n";
cout << "Fuel Type: " << fuelType << "\n";
cout << "Current Location: " << currentLocation << "\n";
telemetry.displayTelemetry();
}

void updateLocation(const char* newLocation) {


strncpy(currentLocation, newLocation, 50);
}

// Friend class declaration


friend class VehicleManager;
};

class VehicleManager {
public:
void trackVehicleLocation(const Vehicle& vehicle) const {
cout << "Tracking Vehicle ID: " << vehicle.vehicleID << ", Current Location: " <<
vehicle.currentLocation << "\n";
}

void writeToFile(Vehicle* vehiclesArray[], int size) const {


ofstream outFile("vehicle_info.txt");
if (!outFile) {
cout << "Error opening file for writing.\n";
return;
}

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


outFile << vehiclesArray[i]->vehicleID << " "
<< vehiclesArray[i]->model << " "
<< vehiclesArray[i]->fuelType << " "
<< vehiclesArray[i]->currentLocation << "\n";
}

outFile.close();
}

void readFromFile() const {


ifstream inFile("vehicle_info.txt");
if (!inFile) {
cout << "Error opening file for reading.\n";
return;
}

char vehicleID[10];
char model[50];
char fuelType[10];
char location[50];

while (inFile >> vehicleID >> model >> fuelType >> location) {
if (strcmp(location, "Karachi") == 0) {
cout << "Vehicle ID: " << vehicleID << ", Model: " << model << ", Fuel Type: " << fuelType
<< ", Location: " << location << "\n";
}
}

inFile.close();
}
};

class MeterReadingVehicle : public Vehicle {


private:
int readingCapacity;

public:
MeterReadingVehicle(const char* vehicleID, const char* model, const char* fuelType, const char*
currentLocation, const TelemetryData& telemetry, int readingCapacity)
: Vehicle(vehicleID, model, fuelType, currentLocation, telemetry), readingCapacity(readingCapacity)
{}

void displayDetails() const override {


Vehicle::displayDetails();
cout << "Reading Capacity: " << readingCapacity << "\n";
}
};

class PipelineInspectionVehicle : public Vehicle {


private:
int inspectionRange;

public:
PipelineInspectionVehicle(const char* vehicleID, const char* model, const char* fuelType, const char*
currentLocation, const TelemetryData& telemetry, int inspectionRange)
: Vehicle(vehicleID, model, fuelType, currentLocation, telemetry), inspectionRange(inspectionRange)
{}
void displayDetails() const override {
Vehicle::displayDetails();
cout << "Inspection Range: " << inspectionRange << " km\n";
}
};

class MaintenanceVehicle : public Vehicle {


private:
int equipmentCapacity;

public:
MaintenanceVehicle(const char* vehicleID, const char* model, const char* fuelType, const char*
currentLocation, const TelemetryData& telemetry, int equipmentCapacity)
: Vehicle(vehicleID, model, fuelType, currentLocation, telemetry),
equipmentCapacity(equipmentCapacity) {}

void displayDetails() const override {


Vehicle::displayDetails();
cout << "Equipment Capacity: " << equipmentCapacity << " units\n";
}
};

int main() {
TelemetryData telemetry(8.5, 60.0, true);
MeterReadingVehicle meterVehicle("V1234", "Toyota Corolla 2022", "Petrol", "Karachi", telemetry,
100);
PipelineInspectionVehicle pipelineVehicle("V5678", "Honda Civic 2023", "Diesel", "Lahore",
telemetry, 200);
MaintenanceVehicle maintenanceVehicle("V9101", "Ford F-150", "Diesel", "Islamabad", telemetry,
300);

meterVehicle.displayDetails();
cout << "-----------------------------------\n";
pipelineVehicle.displayDetails();
cout << "-----------------------------------\n";
maintenanceVehicle.displayDetails();

Vehicle* vehiclesArray[] = { &meterVehicle, &pipelineVehicle, &maintenanceVehicle };


VehicleManager manager;
manager.writeToFile(vehiclesArray, 3);
cout << "-----------------------------------\n";
cout << "Vehicles in Karachi:\n";
manager.readFromFile();
return 0;
}

Question : 5

Note:
1. It is a demo solution. Other solutions can also be correct.
2. For the solution below, I have created both functions as pure virtual in JewelryItem; only one can
be considered correct.

#include <iostream>
#include <string>

using namespace std;

// Abstract class JewelryItem


class JewelryItem {
protected:
string itemCode;
string itemName;
double weightInGrams;
int purity;

public:
JewelryItem(string code, string name, double weight, int pur) : itemCode(code),
itemName(name), weightInGrams(weight), purity(pur) {}
virtual void displayDetails() const = 0;
virtual double calculatePrice() const = 0;
};

// GoldJewelry class derived from JewelryItem


class GoldJewelry : public JewelryItem {
private:
int goldKarat;

public:
GoldJewelry(string code, string name, double weight, int pur) : JewelryItem(code, name, weight,
pur) {}
void setGoldKarat(int karat) {
goldKarat = karat;
}
void displayDetails() const override {
cout << "Item Code: " << itemCode << endl;
cout << "Item Name: " << itemName << endl;
cout << "Weight: " << weightInGrams << " grams" << endl;
cout << "Purity: " << purity << "%" << endl;
cout << "Gold Karat: " << goldKarat << endl;
}
double calculatePrice() const override {
return weightInGrams * (purity / 100.0) * goldKarat * 50; // Example pricing formula
}
};

// DiamondJewelry class derived from JewelryItem


class DiamondJewelry : public JewelryItem {
private:
int numDiamonds;
double diamondCarat;

public:
DiamondJewelry(string code, string name, double weight, int pur) : JewelryItem(code, name,
weight, pur) {}
void addDiamonds(int num, double carat) {
numDiamonds = num;
diamondCarat = carat;
}
void displayDetails() const override {
cout << "Item Code: " << itemCode << endl;
cout << "Item Name: " << itemName << endl;
cout << "Weight: " << weightInGrams << " grams" << endl;
cout << "Purity: " << purity << "%" << endl;
cout << "Number of Diamonds: " << numDiamonds << endl;
cout << "Diamond Carat: " << diamondCarat << endl;
}
double calculatePrice() const override {
return weightInGrams * (purity / 100.0) * diamondCarat * 1000; // Example pricing formula
}
};

// Customer class
class Customer {
private:
string customerID;
string name;
JewelryItem* purchasedGold;
JewelryItem* purchasedDiamond;

public:
Customer(string id, string nm) : customerID(id), name(nm), purchasedGold(NULL),
purchasedDiamond(NULL) {}
void purchaseGold(GoldJewelry* gold) {
purchasedGold = gold;
}
void purchaseDiamond(DiamondJewelry* diamond) {
purchasedDiamond = diamond;
}
double calculateTotalPurchasePrice() const {
double total = 0.0;
if (purchasedGold != NULL) {
total += purchasedGold->calculatePrice();
}
if (purchasedDiamond != NULL) {
total += purchasedDiamond->calculatePrice();
}
return total;
}
};

// StoreInventory class
class StoreInventory {
private:
static const int MAX_ITEMS = 10; // Maximum number of items in the inventory
JewelryItem* inventory[MAX_ITEMS];
int itemCount;

public:
StoreInventory() : itemCount(0) {}

void addItemToInventory(JewelryItem* item) {


if (itemCount < MAX_ITEMS) {
inventory[itemCount++] = item;
} else {
cout << "Inventory is full. Cannot add more items." << endl;
}
}

void displayInventory() const {


if (itemCount == 0) {
cout << "Inventory is empty." << endl;
} else {
cout << "Store Inventory:" << endl;
for (int i = 0; i < itemCount; ++i) {
cout << "Item " << i + 1 << ":" << endl;
inventory[i]->displayDetails();
cout << "Price: $" << inventory[i]->calculatePrice() << endl;
cout << endl;
}
}
}
};

// Operator overloading for comparison of JewelryItem objects based on their price


bool operator<(const JewelryItem& item1, const JewelryItem& item2) {
return item1.calculatePrice() < item2.calculatePrice();
}

bool operator>(const JewelryItem& item1, const JewelryItem& item2) {


return item1.calculatePrice() > item2.calculatePrice();
}

bool operator==(const JewelryItem& item1, const JewelryItem& item2) {


return item1.calculatePrice() == item2.calculatePrice();
}

int main() {
// Example usage
GoldJewelry goldItem1("G1001", "Gold Necklace", 20.5, 95);
goldItem1.setGoldKarat(22);
DiamondJewelry diamondItem1("D2001", "Diamond Ring", 5.2, 99);
diamondItem1.addDiamonds(1 0, 0.5);

GoldJewelry goldItem2("G1002", "Gold Bracelet", 15.0, 90);


goldItem2.setGoldKarat(24);
DiamondJewelry diamondItem2("D2002", "Diamond Earrings", 8.0, 98);
diamondItem2.addDiamonds(6, 0.3);

Customer customer("C001", "John Doe");


customer.purchaseGold(&goldItem1);
customer.purchaseDiamond(&diamondItem1);

StoreInventory inventory;
inventory.addItemToInventory(&goldItem1);
inventory.addItemToInventory(&diamondItem1);
inventory.addItemToInventory(&goldItem2);
inventory.addItemToInventory(&diamondItem2);

cout << "Customer Total Purchase Price: $" << customer.calculateTotalPurchasePrice() << endl;
inventory.displayInventory();

return 0;
}

Question : 6

Note:
1. It is a demo solution. Other solutions can also be correct.

#include <iostream>
#include <string>

using namespace std;

// Custom exception classes


class DuplicateItemException : public exception {
public:
const char* find() const {
return "Duplicate Item Exception";
}
};

class ItemNotFoundException : public exception {


public:
const char* find() const {
return "Item Not Found Exception";
}
};

class OutOfBoundException : public exception {


public:
const char* find() const {
return "Out of bound";
}
};

// Base class for products


class Product {
public:
virtual void print() const = 0;
virtual bool equals(const Product& other) const = 0;
};

// Specific product types


class Book : public Product {
public:
string title;
string author;

Book(const string& bookTitle, const string& bookAuthor) :


title(bookTitle), author(bookAuthor) {}

void print() const override {


cout << "Book: " << title << " by " << author << endl;
}
bool equals(const Product& other) const override {
const Book* otherBook = dynamic_cast<const Book*>(&other);
return otherBook && title == otherBook->title && author == otherBook->author;
}
};

class Electronic : public Product {


public:
string name;
double price;

Electronic(const string& itemName, double itemPrice) :


name(itemName), price(itemPrice) {}

void print() const override {


cout << "Electronic: " << name << " costs $" << price << endl;
}

bool equals(const Product& other) const override {


const Electronic* otherElectronic = dynamic_cast<const Electronic*>(&other);
return otherElectronic && name == otherElectronic->name && price == otherElectronic->price;
}
};

class Clothing : public Product {


public:
string type;
string size;

Clothing(const string& itemType, const string& itemSize) :


type(itemType), size(itemSize) {}

void print() const override {


cout << "Clothing: " << type << " size " << size << endl;
}

bool equals(const Product& other) const override {


const Clothing* otherClothing = dynamic_cast<const Clothing*>(&other);
return otherClothing && type == otherClothing->type && size == otherClothing->size;
}
};

// Define the UniqueCart template class


template<typename T, int MaxItems>
class UniqueCart {
private:
T* items[MaxItems];
int itemCount;

public:
UniqueCart() : itemCount(0) {
for (int i = 0; i < MaxItems; ++i) {
items[i] = NULL;
}
}

~UniqueCart() {
for (int i = 0; i < itemCount; ++i) {
delete items[i];
}
}

// Method to add items to the cart


void add(T* item) {
if (itemCount >= MaxItems) {
throw OutOfBoundException();
}
for (int i = 0; i < itemCount; ++i) {
if (items[i] && items[i]->equals(*item)) {
throw DuplicateItemException();
}
}
items[itemCount++] = item;
cout << "Item added to cart." << endl;
}

// Method to remove items from the cart


void remove(const T& item) {
bool found = false;
for (int i = 0; i < itemCount; ++i) {
if (items[i] && items[i]->equals(item)) {
found = true;
cout << "Item removed from cart." << endl;
delete items[i];
items[i] = NULL;
--itemCount;
// Shift items to fill the gap
for (int j = i; j < itemCount; ++j) {
items[j] = items[j + 1];
}
items[itemCount] = NULL;
break;
}
}
if (!found) {
throw ItemNotFoundException();
}
}

// Method to check if a specific item exists in the cart


bool contains(const T& item) const {
for (int i = 0; i < itemCount; ++i) {
if (items[i] && items[i]->equals(item)) {
return true;
}
}
return false;
}

// Method to print all items in the cart


void print() const {
for (int i = 0; i < itemCount; ++i) {
items[i]->print();
}
}
};

int main() {
// Create a cart that can hold up to 10 items of various types
UniqueCart<Product, 10> cart;

// Add items to the cart


try {
cart.add(new Book("The Great Gatsby", "F. Scott Fitzgerald"));
cart.add(new Electronic("Laptop", 1200.0));
cart.add(new Clothing("T-shirt", "Medium"));
// Adding a duplicate item
// cart.add(new Book("The Great Gatsby", "F. Scott Fitzgerald"));
} catch (const OutOfBoundException& ex) {
cout << "Error: " << ex.find() << endl;
} catch (const DuplicateItemException& ex) {
cout << "Error: " << ex.find() << endl;
}

// Print all items in the cart


cart.print();

// Create items to remove/check


Book book("The Great Gatsby", "F. Scott Fitzgerald");
Electronic laptop("Laptop", 1200.0);

// Remove an item from the cart


try {
cart.remove(book);
// Trying to remove a non-existing item
// cart.remove(laptop);
} catch (const ItemNotFoundException& ex) {
cout << "Error: " << ex.find() << endl;
}

// Check if items are in the cart


cout << "Cart contains The Great Gatsby: " << cart.contains(book) << endl;
cout << "Cart contains Laptop: " << cart.contains(laptop) << endl;

return 0;
}

You might also like