BIT153 · TU past paper
Object Oriented Programming 2082 question paper
The complete TU 2082 exam paper for Object Oriented Programming (BIT153), all 12 questions with solved model answers written to the mark scheme.
Tap a question to open its answer.
- 110 marksConstructor overloadingHideAnswer
Write a program to create a class Student with data members id, name, and marks. Define constructors to initialize data members and demonstrate constructor overloading. Implement member functions to read students details, display them and calculate average marks.[10]
Constructor Overloading with Student Class
Concept
Constructor overloading means defining multiple constructors in the same class with different parameter lists. The compiler selects the appropriate constructor based on the arguments passed during object creation.
Complete C++ Program
#include <iostream> #include <string> using namespace std; class Student { private: int id; string name; float marks[5]; // stores marks of 5 subjects int numSubjects; public: // ----------------------------------------------- // Constructor 1: Default Constructor // Initializes data members with default values // ----------------------------------------------- Student() { id = 0; name = "Unknown"; numSubjects = 5; for (int i = 0; i < numSubjects; i++) { marks[i] = 0.0; } cout << "Default constructor called." << endl; } // ----------------------------------------------- // Constructor 2: Parameterized Constructor // Initializes id and name; marks set to 0 // ----------------------------------------------- Student(int i, string n) { id = i; name = n; numSubjects = 5; for (int j = 0; j < numSubjects; j++) { marks[j] = 0.0; } cout << "Parameterized constructor (id, name) called." << endl; } // ----------------------------------------------- // Constructor 3: Fully Parameterized Constructor // Initializes all data members including marks // ----------------------------------------------- Student(int i, string n, float m[], int num) { id = i; name = n; numSubjects = num; for (int j = 0; j < numSubjects; j++) { marks[j] = m[j]; } cout << "Fully parameterized constructor called." << endl; } // ----------------------------------------------- // Member Function: Read student details // ----------------------------------------------- void readDetails() { cout << "\nEnter Student ID : "; cin >> id; cout << "Enter Student Name : "; cin.ignore(); getline(cin, name); cout << "Enter marks for " << numSubjects << " subjects:" << endl; for (int i = 0; i < numSubjects; i++) { cout << " Subject " << (i + 1) << " : "; cin >> marks[i]; } } // ----------------------------------------------- // Member Function: Display student details // ----------------------------------------------- void displayDetails() { cout << "\n--- Student Details ---" << endl; cout << "ID : " << id << endl; cout << "Name : " << name << endl; cout << "Marks : "; for (int i = 0; i < numSubjects; i++) { cout << marks[i]; if (i < numSubjects - 1) cout << ", "; } cout << endl; cout << "Average: " << calculateAverage() << endl; cout << "-----------------------" << endl; } // ----------------------------------------------- // Member Function: Calculate average marks // ----------------------------------------------- float calculateAverage() { float sum = 0.0; for (int i = 0; i < numSubjects; i++) { sum += marks[i]; } return sum / numSubjects; } }; // ----------------------------------------------- // Main Function: Demonstrates constructor overloading // ----------------------------------------------- int main() { cout << "========================================" << endl; cout << " Constructor Overloading Demo " << endl; cout << "========================================" << endl; // Using Default Constructor cout << "\n[Object 1: Default Constructor]" << endl; Student s1; s1.readDetails(); s1.displayDetails(); // Using Parameterized Constructor (id and name only) cout << "\n[Object 2: Parameterized Constructor (id, name)]" << endl; Student s2(102, "Ram Sharma"); s2.readDetails(); s2.displayDetails(); // Using Fully Parameterized Constructor cout << "\n[Object 3: Fully Parameterized Constructor]" << endl; float m[] = {78.5, 85.0, 90.0, 72.5, 88.0}; Student s3(103, "Sita Thapa", m, 5); s3.displayDetails(); // no need to read; already initialized return 0; }
Sample Output
======================================== Constructor Overloading Demo ======================================== [Object 1: Default Constructor] Default constructor called. Enter Student ID : 101 Enter Student Name : Hari Bahadur Enter marks for 5 subjects: Subject 1 : 75 Subject 2 : 80 Subject 3 : 65 Subject 4 : 90 Subject 5 : 70 --- Student Details --- ID : 101 Name : Hari Bahadur Marks : 75, 80, 65, 90, 70 Average: 76 ----------------------- [Object 2: Parameterized Constructor (id, name)] Parameterized constructor (id, name) called. ... [Object 3: Fully Parameterized Constructor] Fully parameterized constructor called. --- Student Details --- ID : 103 Name : Sita Thapa Marks : 78.5, 85, 90, 72.5, 88 Average: 82.8 -----------------------
Summary Table
Constructor Parameters Purpose Student()None Default values assigned Student(int, string)id, name Partial initialization Student(int, string, float[], int)id, name, marks array and count Complete initialization at the time of object creation
Key Points Demonstrated
Feature Where it appears in the program Constructor overloading Three constructors share the name Studentbut differ in their parameter listsCompile time polymorphism The compiler picks the constructor by matching the argument list, so the choice is made at compile time, not at run time Data hiding id,nameandmarksare private and are reached only through the member functionsMember functions readDetails()takes input,displayDetails()prints the record andcalculateAverage()returns the averageAutomatic invocation No constructor is ever called by name; each runs the moment its object is created The three constructors are legal together because their signatures differ,
Student(),Student(int, string)andStudent(int, string, float[], int), and an overload set is resolved on the number and the type of the arguments only. Note that a return type may not be used to distinguish them, since a constructor has no return type at all.The average is computed as:
$$\text{Average} = \frac{\sum_{i=1}^{n} marks_i}{n}$$
so for the third object the average is (78.5 + 85 + 90 + 72.5 + 88) / 5, which is 82.8 as printed in the sample output.
Conclusion
The program defines a
Studentclass with private data members and three overloaded constructors, then creates one object through each of them to show that the compiler selects the constructor from the argument list. Together with the member functions for reading, displaying and averaging the marks, it demonstrates encapsulation and compile time polymorphism in a single, exam-ready example. - 210 marksMulti-level inheritanceHideAnswer
Explain inheritance with suitable example.Differentiate between single, multiple, and hybrid inheritance.Write a program to show constructor invocation order in multilevel inheritance.[1+4+5]
Inheritance is an Object-Oriented Programming (OOP) concept where a new class (called the derived class or child class) acquires the properties and behaviors (data members and member functions) of an existing class (called the base class...
- 310 marksOperator overloading definition and purposHideAnswer
Explain operator overloading with example?Write a C++ class Number to store an integer. Overload addition (+) and comparison (==) operators, and show conversion between int and Number. Write a program to perform these operations.[2+8]
Operator Overloading in C++
(a) Explanation of Operator Overloading
Operator overloading is a feature of C++ that allows existing operators (such as
+,-,==,<<, etc.) to be given additional meaning when applied to user-defined types (classes/objects). It enables objects of a class to be used with operators in a natural, intuitive way, just like built-in data types.Key Points:
- The keyword
operatorfollowed by the operator symbol is used to define the overloaded function. - Syntax:
return_type operator symbol (parameter list) - It does not change the precedence or associativity of operators.
- At least one operand must be a user-defined type.
(b) C++ Program
#include <iostream> using namespace std; class Number { private: int value; public: // Default constructor Number() { value = 0; } // Parameterized constructor Number(int v) { value = v; } // ----------------------------------------------- // Conversion: int to Number (done via constructor) // Conversion: Number to int (conversion operator) // ----------------------------------------------- operator int() { return value; } // ----------------------------------------------- // Overload addition operator (+) // Number + Number // ----------------------------------------------- Number operator+(const Number& obj) { Number temp; temp.value = this->value + obj.value; return temp; } // ----------------------------------------------- // Overload comparison operator (==) // ----------------------------------------------- bool operator==(const Number& obj) { if (this->value == obj.value) return true; else return false; } // Display function void display() { cout << "Value = " << value << endl; } }; // ----------------------------------------------- // Main function to demonstrate operations // ----------------------------------------------- int main() { // int to Number conversion (via constructor) int x = 10; Number n1 = x; // implicit conversion: int -> Number Number n2(20); // direct initialization Number n3 = 10; // implicit conversion: int -> Number cout << "n1: "; n1.display(); cout << "n2: "; n2.display(); cout << "n3: "; n3.display(); // Addition operator overloading Number n4 = n1 + n2; // calls operator+ cout << "\nAfter n4 = n1 + n2:" << endl; cout << "n4: "; n4.display(); // Comparison operator overloading cout << "\nComparing n1 and n3 (both have value 10):" << endl; if (n1 == n3) cout << "n1 == n3: TRUE" << endl; else cout << "n1 == n3: FALSE" << endl; cout << "\nComparing n1 and n2:" << endl; if (n1 == n2) cout << "n1 == n2: TRUE" << endl; else cout << "n1 == n2: FALSE" << endl; // Number to int conversion (via conversion operator) int result = n4; // implicit conversion: Number -> int cout << "\nNumber to int conversion (n4 -> int): " << result << endl; return 0; }
Output
n1: Value = 10 n2: Value = 20 n3: Value = 10 After n4 = n1 + n2: n4: Value = 30 Comparing n1 and n3 (both have value 10): n1 == n3: TRUE Comparing n1 and n2: n1 == n2: FALSE Number to int conversion (n4 -> int): 30
Explanation of Key Concepts Used
Feature How it is done inttoNumberVia constructor Number(int v)- implicit conversionNumbertointVia conversion operator operator int()+overloadingNumber operator+(const Number& obj)==overloadingbool operator==(const Number& obj)Number n1 = x;calls the constructorNumber(int v), convertinginttoNumber.int result = n4;callsoperator int(), convertingNumbertoint.n1 + n2callsoperator+, returning a newNumberobject with the sum.n1 == n3callsoperator==, returningtrueif values are equal.
- The keyword
- 45 marksDefault argumentsHideAnswer
Explain default arguments and inline functions in C++ with suitable examples. [5]
--- Definition: Default arguments are values provided in a function declaration that are automatically used when the caller does not supply a corresponding argument. They allow a function to be called with fewer arguments than it is defi...
- 55 marksThis pointer concept and usesHideAnswer
What is the use of this pointer? Write a program to demonstrate it. [5]
The
thisPointer in C++Definition and Use
The
thispointer is an implicit pointer available inside every non-static member function of a class. It automatically points to the object that invoked the member function.Uses of
thisPointerUse Description Resolve name conflict Distinguish between member variables and parameters with the same name Return current object Return *thisto enable method chainingPass current object Pass the calling object to another function Self-reference check Check if two pointers point to the same object
Program to Demonstrate
thisPointer#include <iostream> using namespace std; class Student { private: int id; string name; float marks; public: // Use 1: Resolving name conflict between parameter and data member void setData(int id, string name, float marks) { this->id = id; // 'this->id' is member, 'id' is parameter this->name = name; this->marks = marks; } // Use 2: Returning current object to enable method chaining Student& setId(int id) { this->id = id; return *this; // returns reference to calling object } Student& setName(string name) { this->name = name; return *this; } Student& setMarks(float marks) { this->marks = marks; return *this; } void display() { cout << "ID : " << this->id << endl; cout << "Name : " << this->name << endl; cout << "Marks : " << this->marks << endl; } // Use 3: Compare if two objects are the same using this pointer bool isSame(Student &s) { if (this == &s) { return true; // same object in memory } return false; } }; int main() { // Demonstrating Use 1: Resolving name conflict cout << "--- Using setData (name conflict resolution) ---" << endl; Student s1; s1.setData(101, "Ram Sharma", 85.5); s1.display(); // Demonstrating Use 2: Method chaining using *this cout << "\n--- Using Method Chaining ---" << endl; Student s2; s2.setId(102).setName("Sita Thapa").setMarks(90.0); s2.display(); // Demonstrating Use 3: Self-reference check cout << "\n--- Self-reference Check ---" << endl; if (s1.isSame(s1)) { cout << "s1 and s1 are the SAME object." << endl; } if (!s1.isSame(s2)) { cout << "s1 and s2 are DIFFERENT objects." << endl; } return 0; }
Output
--- Using setData (name conflict resolution) --- ID : 101 Name : Ram Sharma Marks : 85.5 --- Using Method Chaining --- ID : 102 Name : Sita Thapa Marks : 90 --- Self-reference Check --- s1 and s1 are the SAME object. s1 and s2 are DIFFERENT objects.
Key Points to Remember
thisis a constant pointer (its address cannot be changed).- It holds the address of the calling object:
this == &callingObject - It is not available in static member functions (static functions have no object context).
- Dereferencing it (
*this) gives the actual calling object.
- 65 marksFriend functionsHideAnswer
Explain friend function and friend class with example. [5]
Friend Function and Friend Class in C++
Friend Function
A friend function is a function that is not a member of a class but has access to the private and protected members of that class. It is declared inside the class using the keyword
friend.Key Points:
- It is defined outside the class scope
- It is not called using an object (no
thispointer) - It can access private data of the class directly
Example of Friend Function
#include <iostream> using namespace std; class Rectangle { private: float length, breadth; public: Rectangle(float l, float b) { length = l; breadth = b; } // Declaring friend function friend float calculateArea(Rectangle r); }; // Definition of friend function (outside the class) float calculateArea(Rectangle r) { // Accessing private members directly return r.length * r.breadth; } int main() { Rectangle rect(5.0, 3.0); cout << "Area = " << calculateArea(rect) << endl; return 0; }Output:
Area = 15
Friend Class
A friend class is a class that is granted access to the private and protected members of another class. When a class is declared as a friend, all member functions of that friend class can access private data of the other class.
Key Points:
- Declared using
friend class ClassName;inside the class - Friendship is not mutual (if A is friend of B, B is not automatically friend of A)
- Friendship is not inherited
Example of Friend Class
#include <iostream> using namespace std; class Engine { private: int horsepower; public: Engine(int hp) { horsepower = hp; } // Declaring Car as a friend class friend class Car; }; class Car { public: void showEngineDetails(Engine e) { // Accessing private member of Engine class cout << "Engine Horsepower: " << e.horsepower << endl; } }; int main() { Engine eng(150); Car car; car.showEngineDetails(eng); return 0; }Output:
Engine Horsepower: 150
Summary Table
Feature Friend Function Friend Class Type A standalone function A complete class Declaration friend returnType funcName();friend class ClassName;Access Private members of one class Private members of another class Membership Not a member of the class Not a member of the class Note: Use of friend functions and classes should be minimized as they break the principle of data encapsulation in Object-Oriented Programming.
- 75 marksEarly binding versus late bindingHideAnswer
Differentiate between early binding and late binding. Write a program to show dynamic polymorphism using virtual function. [2+3]
--- Feature Early Binding (Static Binding) Late Binding (Dynamic Binding) --------- Time of Resolution Resolved at compile time Resolved at run time Mechanism Uses normal functions / function overloading Uses virtual functions Flexibilit...
- 85 marksFunction templatesHideAnswer
What are function templates? Also, write a program that swaps two values using function templates. [1+4]
Function Templates
What are Function Templates?
A function template is a blueprint or formula for creating a family of related functions. It allows a single function definition to work with different data types, where the actual data type is determined at compile time when the function is called.
Key Points:
- Defined using the keyword
templatefollowed by template parameter list - Enables generic programming in C++
- The compiler automatically generates the appropriate function for each data type used
- Avoids code duplication for functions that perform the same operation on different types
Syntax:
template <typename T> return_type function_name(T param1, T param2, ...) { // function body }Here,
Tis a type parameter (placeholder for an actual data type likeint,float,char, etc.)
Program: Swapping Two Values Using Function Templates
#include <iostream> using namespace std; // Function template for swapping two values template <typename T> void swapValues(T &a, T &b) { T temp; temp = a; a = b; b = temp; } int main() { // Swapping two integers int x = 10, y = 20; cout << "Before swap (int): x = " << x << ", y = " << y << endl; swapValues(x, y); cout << "After swap (int): x = " << x << ", y = " << y << endl; cout << endl; // Swapping two floats float p = 3.14, q = 7.77; cout << "Before swap (float): p = " << p << ", q = " << q << endl; swapValues(p, q); cout << "After swap (float): p = " << p << ", q = " << q << endl; cout << endl; // Swapping two characters char c1 = 'A', c2 = 'Z'; cout << "Before swap (char): c1 = " << c1 << ", c2 = " << c2 << endl; swapValues(c1, c2); cout << "After swap (char): c1 = " << c1 << ", c2 = " << c2 << endl; return 0; }
Output
Before swap (int): x = 10, y = 20 After swap (int): x = 20, y = 10 Before swap (float): p = 3.14, q = 7.77 After swap (float): p = 7.77, q = 3.14 Before swap (char): c1 = A, c2 = Z After swap (char): c1 = Z, c2 = A
Explanation
Aspect Detail template <typename T>Declares T as a generic type parameter T &a, T &bPass by reference so original values are modified T tempTemporary variable of the same generic type Compiler behavior Generates separate swapValues<int>,swapValues<float>,swapValues<char>automaticallyAdvantage: Without templates, we would need to write three separate
swapfunctions forint,float, andchar. The function template handles all types with a single definition. - Defined using the keyword
- 95 marksVirtual base class and ambiguity resolutioHideAnswer
Explain ambiguity problem in multiple inheritance with example. How is it resolved using virtual base class? [5]
When a class inherits from two or more base classes that themselves share a common base class, the derived class ends up with multiple copies of the common base class members. This creates ambiguity because the compiler cannot determine ...
- 105 marksException handling definition and purposeHideAnswer
Write a program to handle division by zero exception using try, catch, and throw. [5]
Handling Division by Zero Exception Using try, catch, and throw
Concept
In C++, exception handling uses three keywords:
- try - block of code that may throw an exception
- throw - used to throw/raise an exception when an error occurs
- catch - block that handles the thrown exception
Program
#include <iostream> using namespace std; // Function to perform division double divide(int numerator, int denominator) { if (denominator == 0) { throw "Division by zero is not allowed!"; // throw exception } return (double)numerator / denominator; } int main() { int a, b; cout << "Enter numerator: "; cin >> a; cout << "Enter denominator: "; cin >> b; try { // Code that may cause exception double result = divide(a, b); cout << "Result: " << a << " / " << b << " = " << result << endl; } catch (const char* msg) { // Handle the exception cout << "Exception caught: " << msg << endl; } cout << "Program continues after exception handling." << endl; return 0; }
Sample Output
Case 1: Normal Division
Enter numerator: 10 Enter denominator: 2 Result: 10 / 2 = 5 Program continues after exception handling.Case 2: Division by Zero
Enter numerator: 10 Enter denominator: 0 Exception caught: Division by zero is not allowed! Program continues after exception handling.
Explanation
Keyword Role in Program throwThrows a string message when denominator is 0 tryWraps the call to divide()that may failcatchCatches the thrown string and displays the error - When denominator is not zero, the division executes normally.
- When denominator is zero,
throwtransfers control directly to thecatchblock, skipping the remainingtryblock. - After the
catchblock executes, the program continues normally, demonstrating graceful error handling.
- 115 marksText file reading and writingHideAnswer
Write a C++ program to read a text file named data.txt and display its contents on the screen. Also, count the number of lines, words, and characters in the file and display these counts after showing the file content. [5]
Suppose data.txt contains: Program Output: Concept Description ------ ifstream Used to open and read from a file getline() Reads one complete line at a time inFile check Verifies file was opened successfully line.length() Returns number ...
- 125 marksAbstract classes and concrete classesHideAnswer
What is the difference between abstract class and concrete class? Explain with example. [5]
Abstract Class and Concrete Class in C++
What makes a class abstract in C++
C++ has no
abstractkeyword. A class becomes abstract the moment it declares at least one pure virtual function, written by putting= 0after a virtual member function instead of a body:virtual double area() const = 0; // pure virtual, so the class is abstractAn abstract class cannot be instantiated. The compiler refuses
Shape s;with "cannot declare variable of abstract type". It can still be used as a base type: pointers and references of the abstract type are perfectly legal, and they are exactly how runtime polymorphism is obtained.Because objects are usually deleted through a base pointer, an abstract base class should also declare a virtual destructor, otherwise the derived part of the object is never destroyed.
Key characteristics:
- At least one member function is declared pure virtual with
= 0. - No object of the class can be created, though base pointers and references are allowed.
- It may also contain ordinary data members and fully implemented member functions.
- A derived class stays abstract until it overrides every pure virtual it inherits.
What a concrete class is
A concrete class supplies a body for every function it declares or inherits, so nothing is left unimplemented. It can be instantiated directly, and it is the only kind of class from which real objects are made. A concrete class is very often a class derived from an abstract base that has filled in the missing implementations.
Key characteristics:
- Every inherited pure virtual function has been overridden.
- Objects can be created on the stack, with
new, or inside a container. - It may be a standalone class or the leaf of an inheritance hierarchy.
Comparison
Feature Abstract class Concrete class Instantiation Not possible, only pointers and references Objects can be created directly Functions Has at least one pure virtual ( = 0)Every function has a body How it is declared No keyword, the = 0on a virtual marks itNothing special is written Purpose Defines an interface or a common template Provides a usable, complete type Destructor Should be declared virtualVirtual only if it is itself a base In Java the same idea is written with the
abstractkeyword on the class and on the method; in C++ the= 0on a virtual function carries that meaning by itself.Worked example
#include <iostream> #include <string> // Abstract class: it declares a pure virtual function, so no Shape object can exist. class Shape { protected: std::string color; public: explicit Shape(const std::string& c) : color(c) {} virtual ~Shape() = default; // virtual destructor for safe deletion via a base pointer virtual double area() const = 0; // pure virtual: this is what makes Shape abstract void displayColor() const { // an ordinary member, already implemented std::cout << "Color: " << color << "\n"; } }; // Concrete class: it gives a body to the inherited pure virtual function. class Circle : public Shape { double radius; public: Circle(double r, const std::string& c) : Shape(c), radius(r) {} double area() const override { return 3.14159 * radius * radius; } }; // Another concrete class from the same abstract base. class Rectangle : public Shape { double length, width; public: Rectangle(double l, double w, const std::string& c) : Shape(c), length(l), width(w) {} double area() const override { return length * width; } }; int main() { // Shape s("Red"); // compile error: cannot declare variable of abstract type Shape Circle c(5.0, "Red"); c.displayColor(); std::cout << "Circle area: " << c.area() << "\n"; Rectangle r(4.0, 6.0, "Blue"); r.displayColor(); std::cout << "Rectangle area: " << r.area() << "\n"; const Shape& s = c; // a reference to the abstract type is legal and dispatches virtually std::cout << "Through base reference: " << s.area() << "\n"; return 0; }Output:
Color: Red Circle area: 78.5398 Color: Blue Rectangle area: 24 Through base reference: 78.5398Here
Shapeis the abstract class. It fixes the interface every shape must offer,area(), without deciding how any particular shape computes it, and it supplies one ready made service,displayColor().CircleandRectangleare the concrete classes: each overridesarea(), so each can be instantiated. The commented out line shows the practical difference, since only the concrete types produce objects while the abstract type produces the common contract they all obey. - At least one member function is declared pure virtual with