💻 CSE 2100: Live Practical Lab Test Practice Sheet
Exam Context & Environment
In KUET, a standard 2-1 Lab Test gives you 90 minutes to design, implement, compile, and execute a complete C++ program on your terminal, followed by a desk-side viva where the examiner inspects your code architecture, encapsulation, memory handling, and friend/member function designs line-by-line.
- Time Allowed: 90 Minutes | Total Marks: 20
- Structure: Two parallel sets (Set A and Set B) modeled directly on past exam papers.
📜 General Candidate Instructions
Crucial Lab Rules
- All data members representing internal states must be securely encapsulated (
privateorprotected). Direct member access inmain()results in an automatic 50% penalty.- Do not use global variables.
- Clean compilation is mandatory. Syntax errors preventing compilation will be capped at a maximum of 5 marks.
📋 SET A: Dynamic Inventory Management System (Warehouse Stock)
❓ Question 1: Class Design & Encapsulation [10 Marks]
Design a class named Product to represent item records inside a warehouse. The class must contain:
- Private Data Members:
productID(integer)stockCount(integer)unitPrice(floating-point)
- Public Data Members:
productName(string)category(string)
- Public Member Functions:
assignInitialValues(int id, string name, string cat, int stock, float price): To initialize all data members.restock(int qty): IncrementsstockCountbyqtyand prints a confirmation.shipProduct(int qty): Checks if enough stock is available. If yes, decrementsstockCountbyqty. If not, prints an"Error: Insufficient Stock!"message.displayDetails() const: Prints the product’s ID, name, category, stock count, and total inventory value (stockCount * unitPrice).
❓ Question 2: Same-Class Friend Comparator [5 Marks]
Declare and define a global friend function named compareInventoryValue(const Product& p1, const Product& p2). This function must compare the total inventory value of both products and return the entire Product object that has the higher total value.
❓ Question 3: Array of Objects & main() Execution [5 Marks]
In the main() function:
- Declare an array of 3
Productobjects (Product warehouse[3];). - Write a loop to dynamically populate details for all 3 products from console input.
- Simulate a shipping transaction of 5 units on the first product (
warehouse[0]). - Call the friend function
compareInventoryValueon the first two products and print the name of the product representing the higher asset value. - Loop through and display the final status of all warehouse items.
📋 SET B: Train Ticket Reservation System (KUET Express)
❓ Question 1: Class Design & Encapsulation [10 Marks]
Design a class named Ticket to manage passenger bookings. The class must contain:
- Private Data Members:
bookingID(integer)fare(floating-point)status(character:'C'for Confirmed,'P'for Pending)
- Public Data Members:
passengerName(string)destination(string)
- Public Member Functions:
assignInitialValues(int id, string name, string dest, float price, char stat): To initialize all fields.confirmBooking(): Changesstatusto'C'and prints a confirmation alert.applyDiscount(float percentage): Deducts the specified percentage from thefare(e.g., entering10.0applies a 10% discount).displayTicket() const: Prints the passenger’s name, destination, fare, and readable status (“Confirmed” or “Pending”).
❓ Question 2: Same-Class Friend Comparator [5 Marks]
Declare and define a global friend function named compareFare(const Ticket& t1, const Ticket& t2). This function must compare the fares of both tickets and return the entire Ticket object representing the more expensive journey.
❓ Question 3: Array of Objects & main() Execution [5 Marks]
In the main() function:
- Declare an array of 3
Ticketobjects (Ticket bookings[3];). - Write a loop to dynamically populate booking details for all 3 tickets from console input.
- Apply a 15% discount to the second ticket (
bookings[1]). - Compare the tickets of passenger 1 and passenger 2 using
compareFareand print the passenger name holding the pricier ticket. - Display all ticket details.
💻 Model Solution Code (Set A: Product Inventory)
#include <iostream>
#include <string>
using namespace std;
class Product {
private:
int productID;
int stockCount;
float unitPrice;
public:
string productName;
string category;
// 1. Assign Initial Values
void assignInitialValues(int id, string name, string cat, int stock, float price) {
productID = id;
productName = name;
category = cat;
stockCount = stock;
unitPrice = price;
}
// 2. Restock Operation
void restock(int qty) {
if (qty > 0) {
stockCount += qty;
cout << "Successfully restocked " << qty << " units of " << productName << endl;
}
}
// 3. Ship/Sell Operation
void shipProduct(int qty) {
if (qty <= stockCount) {
stockCount -= qty;
cout << "Successfully shipped " << qty << " units of " << productName << endl;
} else {
cout << "Error: Insufficient Stock for " << productName << "! Available: " << stockCount << endl;
}
}
// Helper getter for total inventory value
float getInventoryValue() const {
return stockCount * unitPrice;
}
// 4. Display Details
void displayDetails() const {
cout << "ID: " << productID
<< " | Name: " << productName
<< " | Category: " << category
<< " | Stock: " << stockCount
<< " | Value: $" << getInventoryValue() << endl;
}
// DECLARING SAME-CLASS FRIEND COMPARATOR
friend Product compareInventoryValue(const Product& p1, const Product& p2);
};
// DEFINING FRIEND FUNCTION (Global scope: no ClassName:: and no friend keyword)
Product compareInventoryValue(const Product& p1, const Product& p2) {
if (p1.getInventoryValue() >= p2.getInventoryValue()) {
return p1; // Returns the entire Product object by value
} else {
return p2;
}
}
int main() {
Product warehouse[3]; // Array of 3 Objects
// 1. Dynamic Input Loop
cout << "=== REGISTER WAREHOUSE PRODUCTS ===" << endl;
for (int i = 0; i < 3; i++) {
int id, stock;
string name, cat;
float price;
cout << "\nEnter Details for Product #" << (i + 1) << endl;
cout << "Enter Product ID: ";
cin >> id;
cin.ignore(); // Clear newline character from input buffer
cout << "Enter Product Name: ";
getline(cin, name);
cout << "Enter Category: ";
getline(cin, cat);
cout << "Enter Stock Count: ";
cin >> stock;
cout << "Enter Unit Price: ";
cin >> price;
warehouse[i].assignInitialValues(id, name, cat, stock, price);
}
// 2. Simulate Shipping Transaction on first product
cout << "\n=== SIMULATING TRANSACTION ===" << endl;
warehouse[0].shipProduct(5); // Attempt to ship 5 units
// 3. Compare Values using Friend Function
cout << "\n=== COMPARING INVENTORY VALUES ===" << endl;
Product higherValued = compareInventoryValue(warehouse[0], warehouse[1]);
cout << "The higher asset-valued product between \"" << warehouse[0].productName
<< "\" and \"" << warehouse[1].productName << "\" is: " << higherValued.productName
<< " (Total Value: $" << higherValued.getInventoryValue() << ")" << endl;
// 4. Final Display Report
cout << "\n=== FINAL INVENTORY REPORT ===" << endl;
for (int i = 0; i < 3; i++) {
warehouse[i].displayDetails();
}
return 0;
}⚠️ Examiner’s Viva Check: Top 3 Desk-Side Traps
Viva Question 1: Friend Function Signature
“Show me your friend function signature. Why does it take two arguments instead of one?”
- Answer: A friend function is a non-member global function, so it does not receive an implicit
thispointer (lesson-5-advanced-inheritance, lesson-6-this-and-operators). Thus, to compare two objects, both must be explicitly passed as parameters. (If it were a member function, it would take only one argument because the invoking object acts as the left-hand side).
Viva Question 2: Pass-by-Const-Reference vs. Pass-by-Value
“What is the performance implication of passing
Product p1by value versusconst Product& p1?”
- Answer: Passing by value (
Product p1) invokes the copy constructor (lesson-3-object-lifecycle), making redundant temporary stack copies of member strings and integers. Passing by const reference (const Product& p1) passes only a memory address (zero copying overhead) whileconstguarantees read-only safety (lesson-2-member-functions-and-arrays).
Viva Question 3: The
cin.ignore()Buffer Flush“Why did you place
cin.ignore()immediately aftercin >> idand beforegetline(cin, name)?”
- Answer: Standard extraction (
cin >> id) leaves a trailing newline character\nin the input stream buffer. If not discarded withcin.ignore(), the subsequentgetline()immediately reads that trailing newline as an empty string, skipping user input for the name (lesson-1-intro-to-oop-and-classes).