Browse papers
A

Section A: Long Answer Questions

Attempt all / any as specified.

4 questions
1long12 marks

(a) Distinguish between a structure and a class in C++ with respect to default access specifiers and member functions. (b) Explain the concept of a constructor and a destructor, stating the rules they must follow. (c) Write a complete C++ program that defines a class BankAccount having private data members accountNo, balance and an owner name. Provide a parameterized constructor to initialize an account, member functions deposit(amount) and withdraw(amount) (the latter must reject withdrawals that exceed the balance), and a destructor that prints a message when an object is destroyed. Demonstrate the class in main().

(a) Structure vs Class in C++

Aspectstructclass
Default access specifier of memberspublicprivate
Default inheritance modepublicprivate
Member functionsAllowed (C++ extends C structs)Allowed
Typical usePlain data aggregates (POD)Full objects with encapsulation

Functionally a struct and a class in C++ are identical except for the default access level: members of a struct are public by default, whereas members of a class are private by default. Both can have member functions, constructors, destructors, and support inheritance.

(b) Constructor and Destructor

Constructor: A special member function that is automatically invoked when an object is created; it initializes the object's data members.

Rules:

  • Has the same name as the class.
  • Has no return type (not even void).
  • Can be overloaded (default, parameterized, copy constructors).
  • Cannot be virtual; can be private (e.g. singletons).

Destructor: A special member function automatically invoked when an object goes out of scope or is deleted; it releases resources held by the object.

Rules:

  • Has the same name as the class prefixed with ~ (e.g. ~BankAccount()).
  • Has no return type and no parameters (cannot be overloaded).
  • Exactly one destructor per class.
  • Should be declared virtual in a base class meant for polymorphic use.

(c) BankAccount Program

#include <iostream>
#include <string>
using namespace std;

class BankAccount {
private:
    int accountNo;
    double balance;
    string name;
public:
    // Parameterized constructor
    BankAccount(int accNo, string owner, double initial)
        : accountNo(accNo), balance(initial), name(owner) {
        cout << "Account " << accountNo << " created for " << name << endl;
    }

    void deposit(double amount) {
        if (amount <= 0) { cout << "Invalid deposit\n"; return; }
        balance += amount;
        cout << "Deposited " << amount << ", balance = " << balance << endl;
    }

    void withdraw(double amount) {
        if (amount > balance) {
            cout << "Withdrawal of " << amount
                 << " rejected: insufficient balance (" << balance << ")\n";
            return;
        }
        balance -= amount;
        cout << "Withdrew " << amount << ", balance = " << balance << endl;
    }

    // Destructor
    ~BankAccount() {
        cout << "Account " << accountNo << " of " << name
             << " is being destroyed\n";
    }
};

int main() {
    BankAccount acc(101, "Ram", 5000.0);
    acc.deposit(2000.0);
    acc.withdraw(3000.0);
    acc.withdraw(10000.0);   // rejected
    return 0;                 // destructor runs here
}

Sample output:

Account 101 created for Ram
Deposited 2000, balance = 7000
Withdrew 3000, balance = 4000
Withdrawal of 10000 rejected: insufficient balance (4000)
Account 101 of Ram is being destroyed
classes-and-objectsconstructors-and-destructors
2long14 marks

(a) Define inheritance and explain the different forms of inheritance (single, multiple, multilevel, hierarchical and hybrid) with a labelled diagram for each. (b) What is the diamond problem in multiple inheritance and how does C++ resolve it using virtual base classes? (c) Using a base class Shape with a virtual function area(), derive classes Circle and Rectangle, and write a program that uses a base-class pointer to demonstrate run-time polymorphism.

(a) Inheritance and its Forms

Inheritance is the OOP mechanism by which a new class (derived/child) acquires the properties and behaviour (data members and member functions) of an existing class (base/parent), promoting code reuse and an is-a relationship.

Single inheritance — one base, one derived:

A  -->  B

Multiple inheritance — a derived class from two or more bases:

A   B
 \ /
  C

Multilevel inheritance — a chain of derivation:

A --> B --> C

Hierarchical inheritance — several derived from one base:

     A
    / \
   B   C

Hybrid inheritance — a combination of the above (e.g. hierarchical + multiple), which gives rise to the diamond shape:

     A
    / \
   B   C
    \ /
     D

(b) The Diamond Problem

In hybrid/multiple inheritance, if B and C both inherit from A, and D inherits from both B and C, then D would receive two copies of A's members, causing ambiguity (e.g. d.x is ambiguous).

C++ resolves this with virtual base classes: declaring A as a virtual base of B and C ensures only one shared copy of A exists in D:

class A { public: int x; };
class B : virtual public A { };
class C : virtual public A { };
class D : public B, public C { };   // single copy of A::x

(c) Run-time Polymorphism with Shape

#include <iostream>
using namespace std;

class Shape {
public:
    virtual double area() const = 0;   // virtual function
    virtual ~Shape() {}
};

class Circle : public Shape {
    double r;
public:
    Circle(double radius) : r(radius) {}
    double area() const override { return 3.14159 * r * r; }
};

class Rectangle : public Shape {
    double l, b;
public:
    Rectangle(double len, double br) : l(len), b(br) {}
    double area() const override { return l * b; }
};

int main() {
    Shape* s;
    Circle c(5);
    Rectangle rect(4, 6);

    s = &c;
    cout << "Circle area = " << s->area() << endl;     // 78.53
    s = &rect;
    cout << "Rectangle area = " << s->area() << endl;  // 24
    return 0;
}

Because area() is virtual, the call through the base pointer s is bound at run time to the correct derived implementation (dynamic dispatch via the vtable).

inheritancepolymorphismvirtual-functions
3long14 marks

(a) What is operator overloading? List the operators that cannot be overloaded in C++ and explain why an overloaded operator cannot change the precedence or arity of the operator. (b) Differentiate between overloading an operator as a member function and as a friend function, giving one situation where a friend function is necessary. (c) Design a class Complex and overload the + operator (as a member function) and the << operator (as a friend function) so that two complex numbers can be added and printed.

(a) Operator Overloading

Operator overloading lets us redefine the behaviour of built-in operators (+, -, ==, <<, etc.) for user-defined types (classes), so objects can be manipulated with natural syntax.

Operators that CANNOT be overloaded:

  • . (member access)
  • .* (pointer-to-member access)
  • :: (scope resolution)
  • ?: (ternary conditional)
  • sizeof
  • typeid

An overloaded operator cannot change the operator's precedence, associativity, or arity (number of operands) because these are fixed by the language grammar at compile time. Overloading only redefines what the operator does for class operands, not how the parser groups expressions; allowing such changes would make code ambiguous and unparseable.

(b) Member Function vs Friend Function Overloading

AspectMember functionFriend function
Left operandMust be an object of the class (implicit this)Passed explicitly as a parameter
ParametersOne fewer (binary op takes 1 arg)Takes all operands explicitly (binary op takes 2 args)
AccessHas implicit access to membersGranted access via friend declaration

Situation where a friend is necessary: When the left operand is not an object of the class, e.g. overloading << for cout << obj. Here the left operand is a std::ostream, which we cannot modify, so the operator must be a friend (or free) function: friend ostream& operator<<(ostream&, const Complex&);. The same applies to 2 + obj where the left operand is a primitive.

(c) Complex Class

#include <iostream>
using namespace std;

class Complex {
    double re, im;
public:
    Complex(double r = 0, double i = 0) : re(r), im(i) {}

    // + as member function
    Complex operator+(const Complex& other) const {
        return Complex(re + other.re, im + other.im);
    }

    // << as friend function
    friend ostream& operator<<(ostream& out, const Complex& c) {
        out << c.re << (c.im >= 0 ? " + " : " - ")
            << (c.im >= 0 ? c.im : -c.im) << "i";
        return out;
    }
};

int main() {
    Complex a(3, 4), b(1, -2);
    Complex c = a + b;       // calls operator+
    cout << "Sum = " << c << endl;   // Sum = 4 + 2i
    return 0;
}
operator-overloadingconstructors-and-destructors
4long10 marks

(a) Explain the difference between a function template and a class template with a suitable example of each. (b) Write a generic function template maximum() that returns the larger of two values of any comparable type. (c) Briefly describe what the Standard Template Library (STL) provides under the categories containers, iterators and algorithms, naming two examples of each.

(a) Function Template vs Class Template

A function template defines a family of functions parameterized by type, so one definition works for many types.

template <class T>
T square(T x) { return x * x; }   // square(3), square(2.5)

A class template defines a family of classes parameterized by type; the type is supplied when an object is created.

template <class T>
class Stack {
    T data[100]; int top = 0;
public:
    void push(T x) { data[top++] = x; }
    T pop() { return data[--top]; }
};
Stack<int> s;        // a Stack of int
Stack<string> ss;    // a Stack of string

Key difference: the compiler deduces a function template's type from its arguments automatically, whereas a class template's type must usually be specified explicitly in angle brackets.

(b) Generic maximum() Template

#include <iostream>
using namespace std;

template <class T>
T maximum(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    cout << maximum(10, 25) << endl;        // 25
    cout << maximum(3.7, 1.2) << endl;      // 3.7
    cout << maximum('a', 'z') << endl;      // z
    return 0;
}

(Works for any type T that supports operator>.)

(c) STL Categories

The Standard Template Library is a collection of generic, template-based components:

  • Containers — data structures that store collections of objects. Examples: vector, list, map, set, deque.
  • Iterators — objects that act like generalized pointers, used to traverse containers and connect them to algorithms. Examples: begin()/end() iterators, iterator, const_iterator, reverse_iterator.
  • Algorithms — generic functions that operate on ranges via iterators. Examples: sort(), find(), count(), for_each(), accumulate().
templates-stlexception-handling
B

Section B: Short Answer Questions

Attempt all / any as specified.

8 questions
5short6 marks

Explain the four pillars of object-oriented programming: encapsulation, abstraction, inheritance and polymorphism. Briefly state how each is supported in C++.

Four Pillars of OOP

  1. Encapsulation — bundling data and the functions that operate on it into a single unit (a class) and restricting direct access to the data. In C++: achieved with classes and the private/protected/public access specifiers; data is hidden and exposed through public member functions (getters/setters).

  2. Abstraction — exposing only the essential features of an object while hiding implementation details. In C++: provided through classes, public interfaces, and abstract classes with pure virtual functions, so the user works with what an object does, not how.

  3. Inheritance — deriving a new class from an existing one to reuse and extend its members (is-a relationship). In C++: expressed as class Derived : public Base { ... };, supporting single, multiple, multilevel, hierarchical and hybrid forms.

  4. Polymorphism — the ability of one interface to behave differently for different types ("one name, many forms"). In C++: compile-time polymorphism via function/operator overloading and templates; run-time polymorphism via virtual functions and base-class pointers/references.

oop-conceptsclasses-and-objects
6short6 marks

What is a copy constructor? When is it invoked? Write the prototype of a copy constructor for a class Student and explain the difference between a shallow copy and a deep copy.

Copy Constructor

A copy constructor is a special constructor that creates a new object as a copy of an existing object of the same class. It takes a reference to an object of the same class as its parameter (passed by reference to avoid infinite recursion).

It is invoked when:

  • An object is initialized from another object: Student b = a; or Student b(a);
  • An object is passed by value to a function.
  • An object is returned by value from a function.

Prototype for class Student:

Student(const Student& other);

Shallow Copy vs Deep Copy

Shallow CopyDeep Copy
What is copiedMember values bit-by-bit, including pointer addressesNew memory is allocated and the pointed-to data is duplicated
Pointer membersBoth objects share the same memoryEach object owns its own memory
RiskDangling pointer / double-free when one object is destroyedSafe; independent objects

The compiler-generated default copy constructor performs a shallow copy, which is fine for classes with no dynamically allocated members. For classes holding raw pointers (dynamic memory), a user-defined copy constructor implementing deep copy is required to avoid sharing and double-free errors.

constructors-and-destructors
7short6 marks

Differentiate between compile-time polymorphism and run-time polymorphism. What is a pure virtual function and how does it make a class abstract? Give a short code fragment.

Compile-time vs Run-time Polymorphism

AspectCompile-time (static)Run-time (dynamic)
BindingEarly binding, resolved at compile timeLate binding, resolved at run time
Achieved byFunction overloading, operator overloading, templatesVirtual functions with base-class pointers/references
SpeedFaster (no lookup)Slight overhead (vtable lookup)
FlexibilityLess flexibleMore flexible/extensible

Pure Virtual Function and Abstract Class

A pure virtual function is a virtual function declared with = 0 and (usually) no definition in the base class:

virtual void draw() = 0;

A class containing at least one pure virtual function becomes an abstract class — it cannot be instantiated and serves only as an interface. Any derived class must override all pure virtual functions to become concrete (instantiable).

class Shape {                 // abstract class
public:
    virtual double area() = 0; // pure virtual function
};

class Circle : public Shape {
    double r;
public:
    Circle(double radius) : r(radius) {}
    double area() override { return 3.14159 * r * r; }
};
// Shape s;     // ERROR: cannot instantiate abstract class
Circle c(5);     // OK
polymorphismvirtual-functions
8short6 marks

Explain the visibility of base-class members in a derived class for public, protected and private modes of inheritance using a table. Which members of the base class are never inherited?

Visibility of Base-Class Members in Derived Class

When a class is derived, the access in the derived class depends on both the member's original access in the base and the mode of inheritance:

Base member accesspublic inheritanceprotected inheritanceprivate inheritance
publicbecomes publicbecomes protectedbecomes private
protectedbecomes protectedbecomes protectedbecomes private
privatenot accessiblenot accessiblenot accessible

Notes:

  • A base class's private members are never directly accessible in the derived class (only indirectly through inherited public/protected functions).

Members Never Inherited

While derived objects contain a base sub-object, the following base-class members are not inherited (the derived class must define its own):

  • Constructors
  • Destructor
  • Copy assignment operator (operator=)
  • friend functions (friendship is not inherited)

(Base private members exist in the object but are inaccessible to the derived class.)

inheritanceclasses-and-objects
9short6 marks

Describe the C++ exception-handling mechanism using try, throw and catch. Write a program that throws and catches a DivideByZero exception when a division by zero is attempted.

C++ Exception-Handling Mechanism

C++ handles run-time errors using three keywords:

  • try — encloses the code that might raise an exception (the protected block).
  • throw — signals (raises) an exception, passing an object/value describing the error.
  • catch — immediately follows the try block and handles an exception of a matching type. Multiple catch blocks may handle different types; catch(...) catches any.

When throw executes, control leaves the try block, the stack unwinds (local objects' destructors run), and the first matching catch handler is executed. If no handler matches, std::terminate() is called.

DivideByZero Program

#include <iostream>
#include <string>
using namespace std;

class DivideByZero {
    string msg;
public:
    DivideByZero(string m) : msg(m) {}
    string what() const { return msg; }
};

double divide(int a, int b) {
    if (b == 0)
        throw DivideByZero("Error: division by zero!");
    return static_cast<double>(a) / b;
}

int main() {
    int x = 10, y = 0;
    try {
        cout << divide(x, y) << endl;
    }
    catch (const DivideByZero& e) {
        cout << e.what() << endl;   // Error: division by zero!
    }
    return 0;
}

Output: Error: division by zero!

exception-handling
10short6 marks

Explain the C++ stream class hierarchy for file handling (ifstream, ofstream, fstream). Write a program that writes three lines of text to a file data.txt and then reads the file back and displays its contents on the screen.

C++ File Stream Hierarchy

C++ file I/O is provided through the <fstream> header. The stream classes derive from the base I/O classes:

          ios
         /   \
   istream     ostream
      |           |
  ifstream     ofstream
         \     /
         iostream
            |
         fstream
  • ifstream — input file stream, used to read from files.
  • ofstream — output file stream, used to write to files.
  • fstream — supports both reading and writing (input and output).

Program: Write then Read data.txt

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    // Write three lines
    ofstream fout("data.txt");
    fout << "First line\n";
    fout << "Second line\n";
    fout << "Third line\n";
    fout.close();

    // Read back and display
    ifstream fin("data.txt");
    string line;
    while (getline(fin, line)) {
        cout << line << endl;
    }
    fin.close();
    return 0;
}

Output:

First line
Second line
Third line
file-io-streams
11short6 marks

Differentiate between text-mode and binary-mode file access in C++. Explain the use of the seekg(), seekp() and tellg() functions for random access of a file with a short example.

Text Mode vs Binary Mode

AspectText modeBinary mode (ios::binary)
Data stored asHuman-readable charactersExact byte image of memory
Newline handlingMay translate \n to/from platform newline (e.g. \r\n)No translation; bytes stored as-is
Number storageConverted to ASCII digitsStored in raw internal representation
UseReadable text filesRecords, structures, images, exact data

Random-Access Functions

  • seekg(pos) — moves the get (read) pointer to a byte position in the input stream.
  • seekp(pos) — moves the put (write) pointer to a byte position in the output stream.
  • tellg() — returns the current position of the get pointer (similarly tellp() for the put pointer).

Forms: seekg(offset, direction) where direction is ios::beg, ios::cur, or ios::end.

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream fin("data.txt");
    fin.seekg(0, ios::end);        // go to end
    streampos size = fin.tellg();  // file size in bytes
    cout << "File size = " << size << " bytes\n";

    fin.seekg(5, ios::beg);        // jump to 6th byte
    char ch;
    fin.get(ch);
    cout << "Character at position 5 = " << ch << endl;
    fin.close();
    return 0;
}
file-io-streams
12short6 marks

(a) What is function overloading and how does it differ from a function template? (b) Explain this pointer with an example, and state why an overloaded assignment operator typically returns *this.

(a) Function Overloading vs Function Template

Function overloading means defining multiple functions with the same name but different parameter lists (different number/types of arguments); the compiler picks the right one by argument matching.

int add(int a, int b);
double add(double a, double b);

A function template writes the logic once with a type parameter, and the compiler generates the needed versions automatically.

template <class T> T add(T a, T b) { return a + b; }

Difference: Overloading requires the programmer to write each version separately and they may have different bodies; a template generates many versions from a single generic body. Use overloading when the logic differs per type; use a template when the same logic applies to all types.

(b) The this Pointer

this is an implicit pointer available inside every non-static member function; it points to the object on which the function was invoked. It is used to disambiguate members from parameters and to return the current object.

class Box {
    int x;
public:
    void setX(int x) { this->x = x; }   // distinguishes member x from parameter x
    Box& operator=(const Box& other) {
        if (this != &other)             // self-assignment check
            x = other.x;
        return *this;                   // return current object
    }
};

Why the overloaded assignment operator returns *this: Returning *this (the current object by reference) enables chained assignments like a = b = c; to work, matching the behaviour of the built-in =, and avoids making an unnecessary copy.

templates-stloperator-overloading

Frequently asked questions

Where can I find the BE Computer Engineering (Pokhara University) Object Oriented Programming in C++ (PU, CMP 162) question paper 2078?
The full BE Computer Engineering (Pokhara University) Object Oriented Programming in C++ (PU, CMP 162) 2078 (regular) question paper is available free on Kekkei. You can read every question online and attempt the paper under timed exam conditions.
Does the Object Oriented Programming in C++ (PU, CMP 162) 2078 paper come with solutions?
Yes. Every question on this Object Oriented Programming in C++ (PU, CMP 162) past paper includes a step-by-step solution, plus instant AI feedback when you attempt it on Kekkei.
How many marks is the BE Computer Engineering (Pokhara University) Object Oriented Programming in C++ (PU, CMP 162) 2078 paper?
The BE Computer Engineering (Pokhara University) Object Oriented Programming in C++ (PU, CMP 162) 2078 paper carries 100 full marks and is meant to be completed in 180 minutes, across 12 questions.
Is practising this Object Oriented Programming in C++ (PU, CMP 162) past paper free?
Yes — reading and attempting this Object Oriented Programming in C++ (PU, CMP 162) past paper on Kekkei is completely free.