← Home

Exam Based Q (PYQ) - Part 1

Questions 1 to 29: High-yield university descriptive questions fully answered and explained.

Unit 1: OOAD, UML & Basic OOP

1. Illustrate class and object with example. [8 Marks]
Answer:
A class is a user-defined blueprint or prototype from which objects are created. It represents the set of properties or methods that are common to all objects of one type.
An object is a basic unit of Object-Oriented Programming and represents real-life entities. An object is an instance of a class. When a class is defined, no memory is allocated but when it is instantiated (i.e., an object is created), memory is allocated.
#include <iostream>
using namespace std;

// Class Definition
class Car {
public:
    string brand;
    int speed;

    void display() {
        cout << "Brand: " << brand << ", Speed: " << speed << " km/h" << endl;
    }
};

int main() {
    // Object Creation
    Car myCar;
    myCar.brand = "Toyota";
    myCar.speed = 120;

    myCar.display(); // Accessing member function
    return 0;
}
Explanation:
Think of a class as the blueprint for a house, and the object as the actual house built from that blueprint. You can build many houses (objects) from one blueprint (class), and each house can have different colors or owners (data), but they all share the same layout (structure/methods).
2. List and discuss the characteristics of object oriented programming language. [4 Marks]
Answer:
The fundamental characteristics of Object-Oriented Programming (OOP) are:
1. Encapsulation: The wrapping up of data and functions into a single unit (called a class). It keeps data safe from outside interference and misuse (Data Hiding).
2. Abstraction: The act of representing essential features without including the background details or explanations. It focuses on the observable behavior of an object.
3. Inheritance: The mechanism by which a class (derived class) can acquire the properties and methods of another class (base class). It supports the concept of hierarchical classification and code reusability.
4. Polymorphism: The ability of a message or function to be displayed or processed in more than one form. It plays an important role in allowing objects having different internal structures to share the same external interface (e.g., Function Overloading, Operator Overloading).

Explanation:
Think of a smartphone. Abstraction is the touch screen (you don't need to know how the circuit board works to use it). Encapsulation is the phone casing protecting the battery and chips. Inheritance is a new iPhone 16 taking all features of iPhone 15 and adding new ones. Polymorphism is the volume button (it lowers media volume in a video, but ringtone volume on the home screen).
3. Discuss the different types of access specifier with suitable examples. [4 Marks]
Answer:
Access specifiers define how the members (attributes and methods) of a class can be accessed.
1. Public (public): Members are accessible from outside the class.
2. Private (private): Members cannot be accessed (or viewed) from outside the class. Only the class's own methods (or friend functions) can access them. This is the default access specifier for a `class`.
3. Protected (protected): Members cannot be accessed from outside the class, however, they can be accessed in inherited (derived) classes.
class AccessDemo {
public:
    int publicVar;    // Accessible anywhere
private:
    int privateVar;   // Accessible only inside AccessDemo
protected:
    int protectedVar; // Accessible inside AccessDemo and derived classes
};
Explanation:
Imagine a hospital. `Public` areas are the lobby and cafeteria (anyone can enter). `Private` areas are the surgical rooms (only specific authorized staff can enter). `Protected` areas are like the staff break room (hospital staff and their authorized visitors/family can enter, but not the general public).
4. Distinguish between aggregation and composition with examples. [4 Marks]
Answer:
* Composition: Represents a strong "has-a" relationship. The child object's lifecycle is strictly dependent on the parent object's lifecycle. If the parent is destroyed, the child objects are also destroyed.
* Example: A `House` and a `Room`. A room cannot exist independently of a house.

* Aggregation: Represents a weak "has-a" relationship. The child object can exist independently of the parent object. If the parent is destroyed, the child objects can continue to exist.
* Example: A `Department` and a `Professor`. A professor can exist independently and belong to a different department if the current one is closed.

Explanation:
Composition is a "death pact." If you delete a `Car` object, its `Engine` object is deleted too because an engine doesn't make sense without a car. Aggregation is a "freelance contract." If you delete a `Library` object, the `Book` objects inside it aren't destroyed; they still exist and can be moved to another library.
5. Write a C++ program to calculate and display the area of a rectangle. [8 Marks]
Answer:
#include <iostream>
using namespace std;

class Rectangle {
private:
    float length;
    float breadth;

public:
    // Function 1: Get values
    void getDimensions() {
        cout << "Enter length: ";
        cin >> length;
        cout << "Enter breadth: ";
        cin >> breadth;
    }

    // Function 2: Calculate area
    float calculateArea() {
        return length * breadth;
    }

    // Function 3: Display area
    void displayArea() {
        cout << "The area of the rectangle is: " << calculateArea() << endl;
    }
};

int main() {
    Rectangle rect;
    rect.getDimensions();
    rect.displayArea();
    return 0;
}
Explanation:
This code demonstrates Encapsulation. `length` and `breadth` are `private`, meaning no outside code in `main()` can directly alter them (e.g., `rect.length = 5` would cause an error). They can only be modified securely through the `public` method `getDimensions()`. This protects the data from invalid changes.
6. A smart home needs a system where doors and windows can be locked/unlocked securely. Write a C++ program. [8 Marks]
Answer:
#include <iostream>
#include <string>
using namespace std;

class SmartSecurity {
private:
    string doorStatus;
    string windowStatus;

public:
    // Constructor
    SmartSecurity(string dStatus = "unlocked", string wStatus = "unlocked") {
        doorStatus = dStatus;
        windowStatus = wStatus;
    }

    void lockAll() {
        doorStatus = "locked";
        windowStatus = "locked";
        cout << "All doors and windows are now LOCKED." << endl;
    }

    void unlockAll() {
        doorStatus = "unlocked";
        windowStatus = "unlocked";
        cout << "All doors and windows are now UNLOCKED." << endl;
    }

    void displayStatus() {
        cout << "Current Status:" << endl;
        cout << "Doors: " << doorStatus << endl;
        cout << "Windows: " << windowStatus << endl;
    }
};

int main() {
    SmartSecurity home; // Initialized to unlocked
    home.displayStatus();
    
    home.lockAll();
    home.displayStatus();
    
    home.unlockAll();
    home.displayStatus();
    
    return 0;
}
Explanation:
This problem tests your ability to use constructors to initialize state. The constructor `SmartSecurity(string dStatus = "unlocked", string wStatus = "unlocked")` uses default arguments. If we create the object without passing arguments (`SmartSecurity home;`), it automatically sets both to "unlocked". This ensures the object starts in a valid, known state.
7. Explain the following UML Class diagram notation with example. [8 Marks]
Answer:
1. Class Notation: A class is represented by a rectangle divided into three compartments: the top contains the Class Name, the middle contains Attributes (variables), and the bottom contains Operations (methods).
* Example: Top: `Student`, Middle: `- rollNo : int`, Bottom: `+ study() : void`.
2. Parameter Directionality: Indicates whether a parameter is input (`in`), output (`out`), or both (`inout`). It is placed before the parameter name in the operations compartment.
* Example: `+ updateScore(in newScore: int, out oldScore: int)`
3. Aggregation Relationships: Represents a "weak has-a" relationship. Drawn as a solid line with a hollow diamond pointing to the class that represents the "whole".
* Example: A hollow diamond on `Department` pointing to a line connected to `Professor`.
4. Composition Relationships: Represents a "strong has-a" relationship. Drawn as a solid line with a filled diamond pointing to the class that represents the "whole".
* Example: A filled diamond on `House` pointing to a line connected to `Room`.
5. Generalization (Inheritance): Represents an "is-a" relationship between a base class and a derived class. Drawn as a solid line with a hollow triangular arrowhead pointing from the child class to the parent class.
* Example: Arrow pointing from `Car` to `Vehicle`.
6. Usage (Dependency) Relationship: Indicates that a change in one class may affect another class that uses it. Drawn as a dashed line with an open arrow pointing to the independent class.
* Example: A dashed arrow from a `Printer` class to a `Document` class indicating the printer depends on the document format.

Explanation:
UML (Unified Modeling Language) is simply a standardized way to draw blueprints for software before you write the code. Think of it like architectural symbols on a floor plan. A hollow diamond means "these things are related but independent" (like furniture in a room), while a filled diamond means "these things are permanently attached" (like a built-in closet).
8. Draw the UML use case diagram for the library management system. [8 Marks]
Answer:
*(Note: As this is a textual medium, I will describe the structure of the UML diagram you must draw).*

* System Boundary: Draw a large rectangle labeled "Library Management System" at the top.
* Actors:
- Draw a stick figure on the left outside the boundary labeled Librarian.
- Draw a stick figure on the right outside the boundary labeled Student.
* Use Cases (Ovals inside the boundary):
1. Add Books
2. Add Student
3. Add Publication
4. Search Book
5. Issue Book
6. Return Book
7. Apply Penalty
8. Penalty Report
9. View Report
10. Change Password
* Relationships (Solid lines connecting Actors to Use Cases):
- Librarian connects to: Add Books, Add Student, Add Publication, Issue Book, Return Book, Apply Penalty, View Report.
- Student connects to: Search Book, Issue Book, Return Book, Penalty Report, Change Password.

Explanation:
A Use Case Diagram shows *what* a system does from the perspective of external users (Actors). It doesn't show code, databases, or internal logic—just the high-level functionalities available to the people interacting with it. The box represents the limits of the software, the stick figures are the users, and the ovals are the buttons/actions they can click.

Unit 2: Constructors, Overloading & Advanced UML

9. Write a C++ program that simulates a bookstore inventory system with constructors. [8 Marks]
Answer:
#include <iostream>
#include <string>
using namespace std;

class Book {
private:
    string title;
    string author;
    float price;

public:
    // 1. Default Constructor
    Book() {
        title = "Unknown Title";
        author = "Unknown Author";
        price = 0.0;
        cout << "Default Constructor called." << endl;
    }

    // 2. Parameterized Constructor
    Book(string t, string a, float p) {
        title = t;
        author = a;
        price = p;
        cout << "Parameterized Constructor called." << endl;
    }

    // 3. Copy Constructor
    Book(const Book &b) {
        title = b.title;
        author = b.author;
        price = b.price;
        cout << "Copy Constructor called." << endl;
    }

    void display() const {
        cout << "Title: " << title << "\nAuthor: " << author << "\nPrice: $" << price << "\n" << endl;
    }
};

int main() {
    Book b1; // Calls default
    b1.display();

    Book b2("The C++ Programming Language", "Bjarne Stroustrup", 59.99); // Calls parameterized
    b2.display();

    Book b3 = b2; // Calls copy constructor
    b3.display();

    return 0;
}
Explanation:
A constructor is a special function called automatically when an object is created to set up its initial state. Constructor Overloading is having multiple constructors with different parameter lists, allowing flexibility in how objects are created. The Copy Constructor takes a `const Reference` (`const Book &b`) to create a new object as an exact duplicate of an existing one, preventing infinite recursive loops during the copy process.
10. Develop a C++ program that utilizes function overloading to calculate the volume. [15 Marks]
Answer:
Method Overloading is a feature in C++ where two or more functions can have the same name but different parameters (different number of parameters, different types of parameters, or both). The compiler determines which function to call based on the arguments passed at compile time (Static Polymorphism).

(Note: Standard function overloading cannot differ ONLY by return type. We satisfy requirement (ii) by changing the parameter type (e.g., from `int` to `double`) while keeping the parameter count the same, which implicitly allows changing the return type).
#include <iostream>
using namespace std;

const double PI = 3.14159;

class VolumeCalculator {
public:
    // 1. Calculate volume of a cube (1 argument, double type)
    double volume(double side) {
        return side * side * side;
    }

    // 2. Calculate volume of a cylinder (2 arguments, double types)
    // Demonstrates: Different number of arguments
    double volume(double radius, double height) {
        return PI * radius * radius * height;
    }

    // 3. Calculate volume of a sphere (1 argument, int type)
    // Demonstrates: Same number of arguments (1), different parameter type, different return type
    float volume(int radius) {
        return (4.0 / 3.0) * PI * radius * radius * radius;
    }
};

int main() {
    VolumeCalculator calc;
    
    // Cube
    cout << "Volume of Cube (side 5.5): " << calc.volume(5.5) << endl;
    
    // Cylinder
    cout << "Volume of Cylinder (r=3.0, h=4.0): " << calc.volume(3.0, 4.0) << endl;
    
    // Sphere
    cout << "Volume of Sphere (r=5): " << calc.volume(5) << endl;
    
    return 0;
}
Explanation:
Function overloading makes code cleaner and easier to read. Instead of naming functions `volumeCube()`, `volumeCylinder()`, and `volumeSphere()`, we just name them all `volume()`. The compiler is smart enough to look at what you pass in (e.g., two numbers vs one number) and figure out which specific version of `volume()` to execute.
11. Write a CPP program to add and subtract two complex numbers using operator overloading. [8 Marks]
Answer:
#include <iostream>
using namespace std;

class Complex {
private:
    float real;
    float imag;

public:
    Complex(float r = 0, float i = 0) {
        real = r;
        imag = i;
    }

    // Overloading '+' operator
    Complex operator+(const Complex& obj) {
        Complex temp;
        temp.real = real + obj.real;
        temp.imag = imag + obj.imag;
        return temp;
    }

    // Overloading '-' operator
    Complex operator-(const Complex& obj) {
        Complex temp;
        temp.real = real - obj.real;
        temp.imag = imag - obj.imag;
        return temp;
    }

    void display() {
        if (imag >= 0)
            cout << real << " + " << imag << "i\n";
        else
            cout << real << " - " << -imag << "i\n";
    }
};

int main() {
    Complex c1(5.5, 3.2);
    Complex c2(1.2, 4.5);

    cout << "First Complex Number: ";
    c1.display();

    cout << "Second Complex Number: ";
    c2.display();

    Complex sum = c1 + c2;
    cout << "Sum: ";
    sum.display();

    Complex diff = c1 - c2;
    cout << "Difference: ";
    diff.display();

    return 0;
}
Explanation:
C++ doesn't know how to add custom objects together natively (what does `c1 + c2` mean?). Operator overloading teaches C++ how to use standard symbols like `+` on your custom classes. When the compiler sees `c1 + c2`, it translates it to a function call: `c1.operator+(c2)`. Inside that function, we manually add the real and imaginary parts and return a new `Complex` object containing the result.
12. Implement a C++ class `FoodOrder` that overloads the + operator to merge two food orders. [8 Marks]
Answer:
#include <iostream>
using namespace std;

class FoodOrder {
private:
    int totalItems;
    float totalPrice;

public:
    // Constructor
    FoodOrder(int items = 0, float price = 0.0) {
        totalItems = items;
        totalPrice = price;
    }

    // Overload the + operator to merge orders
    FoodOrder operator+(const FoodOrder& other) {
        FoodOrder mergedOrder;
        mergedOrder.totalItems = this->totalItems + other.totalItems;
        mergedOrder.totalPrice = this->totalPrice + other.totalPrice;
        return mergedOrder;
    }

    void displayOrder() const {
        cout << "Total Items: " << totalItems << " | Total Price: $" << totalPrice << endl;
    }
};

int main() {
    FoodOrder initialOrder(2, 25.50);
    cout << "Initial Order -> ";
    initialOrder.displayOrder();

    FoodOrder additionalOrder(1, 15.00);
    cout << "Additional Order -> ";
    additionalOrder.displayOrder();

    // Merging orders using overloaded + operator
    FoodOrder finalOrder = initialOrder + additionalOrder;
    
    cout << "--- Merged Final Order ---" << endl;
    finalOrder.displayOrder();

    return 0;
}
Explanation:
This is an applied version of operator overloading. Instead of doing abstract math, we are using `+` to logically combine two distinct shopping carts into one final cart. This makes the `main()` code incredibly readable (`finalOrder = initialOrder + additionalOrder;`) compared to calling clunky methods like `finalOrder = initialOrder.mergeOrders(additionalOrder);`.
13. Elaborate the sequence diagrams on how a user gets a passport from the passport office. [8 Marks]
Answer:
A Sequence Diagram models the flow of logic within your system in a visual manner, specifically focusing on the time ordering of messages.

Scenario Description: Getting a Passport
1. Lifelines (Objects/Actors involved): `User`, `PassportOfficeInterface` (e.g., website/clerk), `VerificationSystem`, `Database`.
2. Sequence of Events (Messages):
* User sends a `submitApplication(details)` message to the PassportOfficeInterface.
* PassportOfficeInterface sends a `verifyDetails()` message to the VerificationSystem.
* VerificationSystem queries the Database with `checkRecords()`.
* Database returns a `recordsValid` response to the VerificationSystem.
* VerificationSystem sends an `approvalStatus()` message back to the PassportOfficeInterface.
* PassportOfficeInterface sends an `issuePassport()` command to internal systems and sends a `notifyUser()` message to the User.

*(In an exam, you must draw this visually with vertical dashed lines for lifelines, horizontal solid arrows for calls, and horizontal dashed arrows for returns. Time progresses from top to bottom).*

Explanation:
Sequence diagrams are like movie scripts for objects. The vertical lines (lifelines) represent the actors standing on stage. The horizontal arrows are the dialogue they speak to each other. By reading from top to bottom, you can see the exact chronological order of how the interaction unfolds.
14. List out the types of Interaction diagram and Notations. Draw the collaboration diagram. [8 Marks]
Answer:
Types of Interaction Diagrams:
1. Sequence Diagram: Emphasizes the time ordering of messages.
2. Collaboration (Communication) Diagram: Emphasizes the structural organization of the objects that send and receive messages.

Notations Used:
* Objects/Roles: Represented as rectangles (e.g., `Customer : Actor`).
* Links: Solid lines connecting objects that communicate.
* Messages: Arrows placed parallel to the links, indicating the direction of communication.
* Sequence Numbers: Numbers placed next to messages (e.g., `1:`, `1.1:`, `2:`) to indicate the order of execution since there is no vertical timeline.

Collaboration Diagram for Flight Reservation:
*Objects:* `Customer`, `BookingSystem`, `FlightDatabase`, `PaymentGateway`.
*Interactions:*
* `Customer` is linked to `BookingSystem`.
* `BookingSystem` is linked to `FlightDatabase` and `PaymentGateway`.
*Messages:*
1. `1: searchFlight()` [Customer $\rightarrow$ BookingSystem]
2. `2: queryAvailability()` [BookingSystem $\rightarrow$ FlightDatabase]
3. `3: selectFlight()` [Customer $\rightarrow$ BookingSystem]
4. `4: processPayment()` [BookingSystem $\rightarrow$ PaymentGateway]
5. `5: confirmBooking()` [BookingSystem $\rightarrow$ Customer]

Explanation:
While Sequence diagrams focus on *when* messages happen (time), Collaboration diagrams focus on *who is talking to whom* (structure). It looks like an org chart or a network map. Because there's no vertical timeline to show the order, we have to explicitly number the message arrows (1, 2, 3...) so developers know the sequence.

Unit 3: Inheritance, Polymorphism & Dynamic UML

15. What are the types of inheritance? Explain with neat diagram and example program. [8 Marks]
Answer:
Inheritance is the process of creating new classes (derived) from existing classes (base).
1. Single Inheritance: One derived class inherits from one base class. (A $\rightarrow$ B)
2. Multiple Inheritance: One derived class inherits from multiple base classes. (A, B $\rightarrow$ C)
3. Multilevel Inheritance: A class is derived from a class which is already derived from another class. (A $\rightarrow$ B $\rightarrow$ C)
4. Hierarchical Inheritance: Multiple derived classes inherit from a single base class. (A $\rightarrow$ B, A $\rightarrow$ C)
5. Hybrid Inheritance: A combination of more than one type of inheritance (e.g., Multilevel + Multiple).

Example Program (Single Inheritance):
#include <iostream>
using namespace std;

// Base Class
class Animal {
public:
    void eat() {
        cout << "Eating..." << endl;
    }
};

// Derived Class
class Dog : public Animal {
public:
    void bark() {
        cout << "Barking..." << endl;
    }
};

int main() {
    Dog d1;
    d1.eat();  // Inherited method
    d1.bark(); // Own method
    return 0;
}
*(In an exam, accompany this with simple block diagrams with arrows showing the flow from Base to Derived classes).*

Explanation:
Inheritance is all about code reuse. Instead of rewriting the `eat()` method for every animal type, you write it once in a Base class and have `Dog`, `Cat`, and `Bird` inherit it. This creates an "IS-A" relationship (`Dog` IS-A `Animal`).
16. Write a C++ Program for the below mentioned hybrid inheritance scenario. [8 Marks]
Answer:
#include <iostream>
#include <string>
using namespace std;

class Student {
protected:
    int rollNo;
    string name;
public:
    void getStudentDetails(int r, string n) {
        rollNo = r;
        name = n;
    }
    void displayStudent() {
        cout << "Name: " << name << ", Roll No: " << rollNo << endl;
    }
};

// Multilevel Inheritance Path
class Marks : public Student {
protected:
    float m1, m2;
public:
    void getMarks(float m1, float m2) {
        this->m1 = m1;
        this->m2 = m2;
    }
    void displayMarks() {
        cout << "Marks: " << m1 << ", " << m2 << endl;
    }
};

// Independent Base Class
class Sports {
protected:
    float sportsScore;
public:
    void getSportsScore(float s) {
        sportsScore = s;
    }
    void displaySports() {
        cout << "Sports Score: " << sportsScore << endl;
    }
};

// Multiple Inheritance Path forming Hybrid
class Results : public Marks, public Sports {
public:
    void displayResult() {
        displayStudent();
        displayMarks();
        displaySports();
        float total = m1 + m2 + sportsScore;
        cout << "Total Marks: " << total << endl;
        cout << "Average: " << total / 3.0 << endl;
    }
};

int main() {
    Results res;
    res.getStudentDetails(101, "Alice");
    res.getMarks(85.5, 90.0);
    res.getSportsScore(95.0);
    
    cout << "--- Student Result Card ---" << endl;
    res.displayResult();
    
    return 0;
}
Explanation:
Hybrid inheritance is a combination of two or more types of inheritance. Here, `Marks` inherits `Student` (Single/Multilevel Inheritance), and `Result` inherits from both `Marks` and `Sports` (Multiple Inheritance). This allows the `Results` object to seamlessly access the data and methods from all three parent classes in the hierarchy.
17. Write a C++ program for the inheritance scenario (Shape, Polygon, Rectangle, Triangle, Square). [15 Marks]
Answer:
#include <iostream>
using namespace std;

class Shape {
public:
    void print() {
        cout << "This is a shape" << endl;
    }
};

class Polygon : public Shape {
public:
    void print() {
        cout << "Polygon is a shape" << endl;
    }
};

class Rectangle : public Polygon {
public:
    void print() {
        cout << "Rectangle is a polygon" << endl;
    }
};

class Triangle : public Polygon {
public:
    void print() {
        cout << "Triangle is a polygon" << endl;
    }
};

class Square : public Rectangle {
public:
    void print() {
        cout << "Square is a rectangle" << endl;
    }
};

int main() {
    Shape s;
    Polygon p;
    Rectangle r;
    Triangle t;
    Square sq;

    s.print();
    p.print();
    r.print();
    t.print();
    sq.print();

    return 0;
}
Explanation:
This is an exercise in Method Overriding (or shadowing, since we aren't using `virtual` here). Each derived class provides its own specific implementation of the `print()` function. When you create a `Square` object and call `sq.print()`, the compiler executes the `print()` defined inside the `Square` class, ignoring the inherited versions from `Rectangle`, `Polygon`, or `Shape`.
18. Write a CPP program to differentiate early binding and late binding with the help of virtual functions. [8 Marks]
Answer:
#include <iostream>
using namespace std;

class Base {
public:
    // Non-virtual function (Early Binding)
    void show() {
        cout << "Base class show() function - Early Binding" << endl;
    }
    
    // Virtual function (Late Binding)
    virtual void print() {
        cout << "Base class print() function - Late Binding" << endl;
    }
};

class Derived : public Base {
public:
    void show() {
        cout << "Derived class show() function" << endl;
    }
    
    void print() override {
        cout << "Derived class print() function - Late Binding" << endl;
    }
};

int main() {
    Base* basePtr;
    Derived derivedObj;

    // Point base pointer to derived object
    basePtr = &derivedObj;

    cout << "--- Early Binding Demonstration ---" << endl;
    // Early binding: Compiler looks at pointer type (Base*) and calls Base::show()
    basePtr->show(); 

    cout << "\n--- Late Binding Demonstration ---" << endl;
    // Late binding: Runtime looks at actual object type (Derived) and calls Derived::print()
    basePtr->print();

    return 0;
}
Explanation:
When using a Base class pointer to point to a Derived class object, the compiler gets confused. Without the `virtual` keyword, the compiler looks at the pointer type (`Base*`) during compilation and rigidly binds it to the Base method (Early Binding). With the `virtual` keyword, the compiler waits until the program is actually running, checks what object the pointer is *actually* pointing to in memory (`Derived`), and executes the Derived method (Late Binding via VTable).
19. Consider a scenario where you are developing a banking application in C++. How does the implementation of OOP concepts... [15 Marks]
Answer:
Theoretical Contribution:
* Encapsulation: Secures customer data (like balances and PINs) by making them private, preventing unauthorized external access.
* Inheritance: Allows the creation of specialized account types (Savings, Current) from a general `Account` class, reducing code duplication.
* Polymorphism: Allows generic functions to process any account type using a base pointer, calculating correct interest rates at runtime via virtual functions.

C++ Program Implementation:
#include <iostream>
#include <string>
using namespace std;

// Base Class: Demonstrates Abstraction and Class design
class Account {
// Encapsulation: Sensitive data is hidden
protected:
    string accountHolder;
    double balance;

public:
    // Constructor
    Account(string name, double initialBalance) {
        accountHolder = name;
        balance = initialBalance;
    }

    // Methods for basic operations
    void deposit(double amount) {
        balance += amount;
    }

    // Virtual function enables Polymorphism (Late Binding)
    virtual void calculateInterest() = 0; // Pure virtual function

    virtual void display() {
        cout << "Account Holder: " << accountHolder << " | Balance: $" << balance << endl;
    }
    
    // Virtual destructor is crucial for polymorphic base classes
    virtual ~Account() {} 
};

// Inheritance: SavingsAccount IS-A Account
class SavingsAccount : public Account {
private:
    double interestRate;

public:
    // Constructor calling base constructor
    SavingsAccount(string name, double balance, double rate) : Account(name, balance) {
        interestRate = rate;
    }

    // Polymorphism: Overriding the base method
    void calculateInterest() override {
        double interest = balance * (interestRate / 100);
        balance += interest;
        cout << "Interest added: $" << interest << endl;
    }
};

int main() {
    // Objects: Instantiating the class
    Account* myAccount = new SavingsAccount("John Doe", 1000.0, 5.0);

    myAccount->display();
    
    // Polymorphic call
    myAccount->calculateInterest(); 
    
    myAccount->display();

    delete myAccount;
    return 0;
}
Explanation:
This question wants you to tie everything together. The program demonstrates that by using a pure virtual function `calculateInterest()`, the banking application can loop through an array of thousands of generic `Account*` pointers, call `calculateInterest()`, and let runtime polymorphism automatically apply the correct math whether it's a Savings, Checking, or Loan account, without writing messy `if-else` type checks.
20. Construct activity diagram for the given scenario using fork and join operation. [8 Marks]
Answer:
An Activity Diagram represents the workflow of a system.
Component Explanation:
* Initial Node: Solid black circle representing the start of the flow.
* Action Nodes (Rounded Rectangles): "Login", "Access Menu", "Select Items".
* Fork (Thick black bar): Splits a single flow into multiple concurrent flows. E.g., splitting after "Select Items" into "Prepare Food in Kitchen" and "Make Payment".
* Join (Thick black bar): Synchronizes multiple concurrent flows back into a single flow. E.g., joining "Food Prepared" and "Payment Confirmed" before moving to "Serve Food".
* Final Node: Bullseye symbol representing the end of the process.

*(Drawing instructions for exam):*
Start Node $\rightarrow$ [Login] $\rightarrow$ [Access Menu] $\rightarrow$ [Select Items] $\rightarrow$ FORK BAR.
From Fork Bar, draw two parallel arrows. Arrow 1 $\rightarrow$ [Make Payment]. Arrow 2 $\rightarrow$ [Update Inventory].
Both parallel paths lead into a JOIN BAR.
From Join Bar $\rightarrow$ [Confirm Order] $\rightarrow$ Final Node.

Explanation:
Activity diagrams are essentially advanced flowcharts. They show the step-by-step control flow of a business process. The "Fork" and "Join" bars are the key here; they indicate parallel processing (e.g., the kitchen cooks the food *while* the payment is processing concurrently, rather than waiting for one to finish before starting the other).
21. Draw the State chart diagram with three different states for Order Management System. [8 Marks]
Answer:
A State Chart Diagram models the dynamic behavior of a single object, showing its transitions between various states over its lifetime.

States for an Order:
1. Pending: The initial state when the order is placed but payment is not confirmed.
2. Processing: The state after successful payment.
3. Shipped/Completed: The final state when the order leaves the facility.

*(Drawing instructions for exam):*
* Initial State (Black Circle): Arrow points to [Pending].
* State 1: [Pending]:
    * Self-transition loop: `updateCart()`
    * Transition arrow to Choice Pseudostate (Diamond) triggered by `processPayment()`.
* Choice Pseudostate (Diamond):
    * If payment fails $\rightarrow$ Arrow back to [Pending].
    * If payment success $\rightarrow$ Arrow to [Processing].
* State 2: [Processing]:
    * Entry action: `entry / deductInventory()`
    * Exit action: `exit / printShippingLabel()`
    * Transition arrow to [Shipped] triggered by `dispatchPackage()`.
* State 3: [Shipped]: Transition to Final State (Bullseye).

Explanation:
While an Activity diagram shows a process, a State diagram tracks the lifecycle of a *single object*. In this case, an "Order" object. The object sits in the "Pending" state until an event (like a payment) triggers a transition. The entry/exit actions define automated tasks that fire the moment the object enters or leaves a specific state.

Unit 4: Templates, Exceptions & Structural UML

22. Write a simple Calculator Program performing four basic arithmetic operations in C++ using a class template. [8 Marks]
Answer:
#include <iostream>
using namespace std;

template <class T>
class Calculator {
private:
    T num1, num2;

public:
    // Constructor taking generic datatypes
    Calculator(T n1, T n2) {
        num1 = n1;
        num2 = n2;
    }

    T addition() { return num1 + num2; }
    T subtraction() { return num1 - num2; }
    T multiplication() { return num1 * num2; }
    
    T division() { 
        if (num2 == 0) {
            cout << "Error: Division by zero" << endl;
            return 0;
        }
        return num1 / num2; 
    }

    void show() {
        cout << "Numbers are: " << num1 << " and " << num2 << endl;
        cout << "Addition: " << addition() << endl;
        cout << "Subtraction: " << subtraction() << endl;
        cout << "Multiplication: " << multiplication() << endl;
        cout << "Division: " << division() << endl;
        cout << "------------------------" << endl;
    }
};

int main() {
    // Instantiating for integers
    Calculator<int> intCalc(20, 5);
    cout << "Integer Calculator Results:" << endl;
    intCalc.show();

    // Instantiating for floating point numbers
    Calculator<float> floatCalc(15.5, 2.5);
    cout << "Float Calculator Results:" << endl;
    floatCalc.show();

    return 0;
}
Explanation:
Class templates allow us to write generic, type-independent code. Instead of duplicating the entire `Calculator` class once for `int` and once for `float`, we use a generic placeholder `T`. The compiler automatically generates the correct, type-specific class behind the scenes when we instantiate it in `main()` using `Calculator` or `Calculator`.
23. Create an integer vector object vect1. Insert 5 elements. Use multiple catch block exception handling... [8 Marks]
Answer:
#include <iostream>
#include <vector>
#include <stdexcept> // For standard exceptions
using namespace std;

void testExceptions(int code, vector<int>& v) {
    try {
        if (code == 1) {
            cout << "Attempting Bound Violation..." << endl;
            // vector::at() throws out_of_range exception if index is invalid
            cout << v.at(10) << endl; 
        } 
        else if (code == 2) {
            cout << "Attempting Null Pointer access..." << endl;
            int* ptr = nullptr;
            if (ptr == nullptr) {
                throw runtime_error("Null Pointer Exception");
            }
            cout << *ptr << endl;
        } 
        else if (code == 3) {
            cout << "Attempting Type Conversion Error..." << endl;
            throw invalid_argument("Invalid Type Cast / Value Exception");
        }
    }
    // Multiple Catch Blocks
    catch (const out_of_range& e) {
        cout << "Caught Bound Violation: " << e.what() << endl;
    } 
    catch (const runtime_error& e) {
        cout << "Caught Bad Reference: " << e.what() << endl;
    } 
    catch (const invalid_argument& e) {
        cout << "Caught Type Conversion Error: " << e.what() << endl;
    } 
    catch (...) {
        cout << "Caught an unknown exception!" << endl;
    }
    cout << "------------------------" << endl;
}

int main() {
    vector<int> vect1;
    
    // Inserting elements
    vect1.push_back(10);
    vect1.push_back(20);
    vect1.push_back(30);
    vect1.push_back(40);
    vect1.push_back(50);

    testExceptions(1, vect1); // Trigger bounds error
    testExceptions(2, vect1); // Trigger null pointer error
    testExceptions(3, vect1); // Trigger type error

    return 0;
}
Explanation:
Exception handling (`try-catch-throw`) separates error-handling logic from regular code. When a runtime error occurs, the code `throw`s an object (an exception). Execution immediately jumps out of the `try` block and searches top-to-bottom for the first `catch` block that matches the thrown object type. Multiple catch blocks allow specific handling for different errors. The `catch(...)` block is a "catch-all" safety net that must always be placed last.
24. A university conducts examinations and results are announced. Draw UML component diagrams for the report... [15 Marks]
Answer:
Problem Statement: Design a University Exam Result system that processes raw student data to generate sorted mark lists, arrear lists, and departmental rank lists.

Components Identified:
1. Database Component: Stores student records, marks, and registry numbers.
2. Processing Engine Component: Handles the sorting algorithms, filtering logic for arrears, and ranking calculations.
3. Reporting Interface Component: Generates the final views (Mark List View, Arrear View, Rank View).

Component Diagram Notations:
* Component: Represented as a rectangle with a smaller rectangle icon in the top right corner (or two smaller rectangles sticking out the left side). Represents a modular, replaceable part of the system.
* Provided Interface: Represented by a "lollipop" (a solid circle connected by a line to the component). It shows the services the component offers to others.
* Required Interface: Represented by a "socket" (a half-circle connected by a line to the component). It shows the services the component needs from others.
* Dependency: A dashed arrow indicating that one component requires another to function.

*(Drawing instructions for exam):*
Draw three large boxes (Components).
Box 1: `[Database]`. It has a Provided Interface (Lollipop) labeled "Student Data".
Box 2: `[Processing Engine]`. It has a Required Interface (Socket) that connects to the "Student Data" lollipop. It has a Provided Interface labeled "Calculated Results".
Box 3: `[Reporting UI]`. It has a Required Interface connecting to "Calculated Results".

Explanation:
Component diagrams show the high-level physical architecture of software. Think of them like LEGO blocks. The "Database" component provides data (the lollipop). The "Processing Engine" needs data, so it plugs into that lollipop (the socket). This allows teams to work on different components independently as long as the interfaces match.

Unit 5: Standard Template Library (STL)

25. Explain in detail about the components that make up the Standard Template Libraries (STL). [8 Marks]
Answer:
The STL is a powerful software library in C++ that provides a set of generalized, template-based classes and functions. It consists of three primary components:
1. Containers: These are objects that store collections of data. They manage memory automatically.
    * Sequence Containers: Store data linearly (e.g., `vector`, `list`, `deque`).
    * Associative Containers: Store data in sorted order, usually as key-value pairs using trees (e.g., `set`, `map`).
    * Container Adapters: Provide a restricted interface to sequence containers (e.g., `stack`, `queue`).
2. Algorithms: These are global functions that perform operations on the contents of containers, such as searching, sorting, counting, and manipulating data. They are designed to work across different container types. Examples include `std::sort()`, `std::find()`, `std::reverse()`.
3. Iterators: These act as a bridge between Containers and Algorithms. They are objects that point to elements within a container, functioning much like standard pointers. They allow algorithms to traverse containers without needing to know the specific internal memory structure of that container.

Explanation:
The STL is like a professional kitchen toolbox. The Containers are the bowls and pans that hold the ingredients. The Algorithms are the blenders and ovens that process the ingredients. The Iterators are the spoons that move ingredients from the bowls to the blender. Because they are decoupled, you can use the same `sort()` algorithm on a `vector` or a `deque`.
26. Write a C++ program for sequence container list using array of integer data type and implement the methods. [8 Marks]
Answer:
#include <iostream>
#include <list>
using namespace std;

// User defined function to print a list
void PrintList(const list<int>& lst) {
    for (int val : lst) {
        cout << val << " ";
    }
    cout << endl;
}

int main() {
    // Using an array to initialize the list
    int arr[] = {30, 10, 50, 20};
    list<int> myList(arr, arr + 4);

    cout << "Initial list: ";
    PrintList(myList);

    // (i) push_front()
    myList.push_front(5);
    cout << "After push_front(5): ";
    PrintList(myList);

    // (ii) insert() - inserting 99 at the 2nd position
    auto it = myList.begin();
    advance(it, 1);
    myList.insert(it, 99);
    cout << "After insert(99): ";
    PrintList(myList);

    // (vi) pop_back()
    myList.pop_back();
    cout << "After pop_back(): ";
    PrintList(myList);

    // (iii) sort()
    myList.sort();
    cout << "After sort(): ";
    PrintList(myList);

    // Creating a second list for splice and merge
    list<int> list2 = {7, 15, 25};

    // (iv) splice() - transferring elements from list2 to myList
    myList.splice(myList.end(), list2);
    cout << "After splicing list2 into myList: ";
    PrintList(myList);
    // Note: list2 is now empty

    // (v) merge() - merging requires both lists to be sorted
    list<int> list3 = {2, 40, 60};
    myList.sort(); 
    list3.sort();
    myList.merge(list3); // Merges list3 into myList and keeps it sorted
    cout << "After merge() with list3: ";
    PrintList(myList);

    return 0;
}
Explanation:
A `std::list` is a doubly-linked list. Unlike a `vector`, it does not have contiguous memory, which means you cannot access elements via index (`myList[2]`). However, inserting elements in the middle of a list is much faster than a vector because it only requires updating pointers, not shifting the entire array. Note that `list` requires its own member function `.sort()` because the global `std::sort()` algorithm requires random-access iterators, which `list` does not have.
27. Elaborate in detail about Associative Containers: Map, Multi-map and Set, Multi-set with example program. [8 Marks]
Answer:
Associative containers automatically sort their elements and are highly efficient for search operations (usually implemented internally as Red-Black Trees with $O(\log n)$ complexity).
* `set`: Stores unique elements. Once stored, elements cannot be modified (only removed and re-added). It automatically sorts elements in ascending order.
* `multiset`: Similar to a `set`, but allows duplicate elements.
* `map`: Stores elements as key-value pairs. Keys must be unique, and the map is automatically sorted by the keys.
* `multimap`: Similar to a `map`, but allows multiple identical keys.

Example Program:
#include <iostream>
#include <set>
#include <map>
using namespace std;

int main() {
    // Set Example
    set<int> mySet = {5, 2, 8, 5}; // Duplicate 5 will be ignored
    cout << "Set elements (sorted, unique): ";
    for (int x : mySet) cout << x << " ";
    cout << endl;

    // Map Example
    map<string, int> myMap;
    myMap["Apple"] = 10;
    myMap["Banana"] = 5;
    myMap["Cherry"] = 20;
    
    cout << "\nMap elements (sorted by key): \n";
    for (auto const& pair : myMap) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}
Explanation:
Associative containers are optimized for retrieval. If you need to check if a specific username exists among a million users, a `set` will find it almost instantly using a binary search tree approach, whereas a `vector` would require checking every single name one by one. `Maps` are essentially dictionaries where you look up a definition (value) using a specific word (key).
28. Write a C++ program to demonstrate the working of STL and perform operations in the STL queue and map. [8 Marks]
Answer:
#include <iostream>
#include <queue>
#include <map>
using namespace std;

int main() {
    cout << "--- STL Queue Operations ---" << endl;
    queue<int> q;
    
    // (i) Insert
    q.push(10);
    q.push(20);
    q.push(30);
    cout << "Inserted 10, 20, 30 into Queue." << endl;
    
    // (iii) Display (Requires popping to view)
    cout << "Displaying and (ii) Deleting Queue elements: ";
    while (!q.empty()) {
        cout << q.front() << " "; // Display front
        q.pop(); // Delete front
    }
    cout << "\n(iv) Note: Queue does not support finding elements via iterators without emptying it.\n";

    cout << "\n--- STL Map Operations ---" << endl;
    map<int, string> m;
    
    // (i) Insert
    m.insert({1, "Alice"});
    m[2] = "Bob";
    m[3] = "Charlie";
    
    // (iii) Display
    cout << "Map contents: " << endl;
    for (auto const& pair : m) {
        cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
    }
    
    // (ii) Delete
    m.erase(2); // Remove Bob
    cout << "Map contents after deleting ID 2: " << endl;
    for (auto const& pair : m) {
        cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
    }
    
    // (iv) Find
    cout << "Searching for ID 3..." << endl;
    auto it = m.find(3);
    if (it != m.end()) {
        cout << "Found: " << it->second << endl;
    } else {
        cout << "Not found." << endl;
    }

    return 0;
}
Explanation:
A `queue` is a Container Adapter that strictly enforces a First-In-First-Out (FIFO) logic, like a line at a ticket counter. You cannot iterate through it or "find" an element in the middle; you can only look at the `front()` and remove it with `pop()`. A `map` allows direct access and searching via its keys in logarithmic time using the `.find()` method.
29. Write a C++ program to demonstrate working of `sort()`, `copy()`, `swap()`, `merge()`, `replace()` and `remove()` algorithms. [8 Marks]
Answer:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void print(const string& msg, const vector<int>& v) {
    cout << msg << ": ";
    for (int i : v) cout << i << " ";
    cout << endl;
}

int main() {
    vector<int> v1 = {5, 2, 8, 1, 9};
    vector<int> v2 = {10, 20, 30};
    
    print("Initial v1", v1);
    
    // 1. sort()
    sort(v1.begin(), v1.end());
    print("After sort(v1)", v1);
    
    // 2. copy()
    vector<int> v3(v1.size());
    copy(v1.begin(), v1.end(), v3.begin());
    print("After copy (v1 to v3)", v3);
    
    // 3. swap()
    swap(v1, v2);
    cout << "\nAfter swap(v1, v2):" << endl;
    print("v1", v1);
    print("v2", v2);
    
    // 4. merge()
    // Note: Merge requires both vectors to be sorted. v2 is sorted, let's sort v1.
    sort(v1.begin(), v1.end());
    vector<int> mergedVec(v1.size() + v2.size());
    merge(v1.begin(), v1.end(), v2.begin(), v2.end(), mergedVec.begin());
    print("\nAfter merge(v1, v2)", mergedVec);
    
    // 5. replace()
    replace(mergedVec.begin(), mergedVec.end(), 10, 99);
    print("\nAfter replace (10 with 99)", mergedVec);
    
    // 6. remove() 
    // remove() shifts elements but doesn't resize vector. Erase is needed.
    auto it = remove(mergedVec.begin(), mergedVec.end(), 20);
    mergedVec.erase(it, mergedVec.end());
    print("After remove(20) and erase", mergedVec);

    return 0;
}
Explanation:
STL Algorithms are generic functions that apply logic across a specific range of elements, defined by passing iterators (like `.begin()` and `.end()`). A critical concept here is the "Erase-Remove Idiom." The `remove()` algorithm does not actually delete elements from memory; it merely shifts the non-removed elements to the front of the vector and returns an iterator to the new logical end. You must explicitly call `.erase()` to resize the vector and destroy the leftover data at the back.
✨ C++ Doubt Solver
Namaste! Main aapka C++ AI Assistant hoon. Exams ki taiyari mein aapki madad ke liye hazir hoon. Mujhse kuch bhi puchiye!

🚀 Live C++ Compiler