Unit 1: Principles of OOP and C++ Essentials - Subjective Questions
CAP455 — Object Oriented Programming Using C++ • Practice Questions with Detailed Answers
20 questions
Compare the procedural programming paradigm with the object-oriented programming paradigm.
Procedural programming organizes a program around functions or procedures, whereas object-oriented programming (OOP) organizes it around objects that combine data and behavior.
| Basis | Procedural Programming | Object-Oriented Programming |
|---|---|---|
| Primary unit | Function or procedure | Class and object |
| Approach | Top-down | Bottom-up |
| Data handling | Data is often shared among functions | Data is encapsulated within objects |
| Security | Limited data hiding | Supports data hiding through access specifiers |
| Reusability | Mainly through functions | Through inheritance, composition, and polymorphism |
| Maintenance | Difficult for large programs | Easier because the system is divided into classes |
| Examples | C, Pascal | C++, Java, C# |
Major principles of OOP:
- Encapsulation: Bundling data and functions in a class.
- Abstraction: Showing essential features while hiding implementation details.
- Inheritance: Creating a new class from an existing class.
- Polymorphism: Allowing one interface to represent multiple implementations.
OOP is generally preferred for large and complex software because it improves modularity, maintainability, security, and code reuse.
Explain input and output streams in C++ with suitable examples.
A stream is a sequence of bytes flowing between a program and an input or output device. C++ provides stream classes through the <iostream> header.
Standard stream objects:
std::cin: Reads data from standard input, usually the keyboard.std::cout: Writes normal output to the screen.std::cerr: Writes unbuffered error messages.std::clog: Writes buffered diagnostic messages.
Operators:
- The extraction operator
>>obtains data from an input stream. - The insertion operator
<<sends data to an output stream.
Example:
#include <iostream>
#include <string>
int main() {
std::string name;
int age;
std::cout << "Enter name and age: ";
std::cin >> name >> age;
std::cout << "Name: " << name << ", Age: " << age;
return 0;
}The operators can be chained because each operation returns the stream object. For example, std::cout << a << b; performs two consecutive insertion operations.
Define a class and an object in C++. Explain their relationship and the role of access specifiers.
A class is a user-defined data type that groups data members and member functions into a single unit. An object is an instance of a class.
Relationship:
- A class acts as a blueprint.
- Objects are concrete entities created from that blueprint.
- Every object has its own copy of non-static data members.
- Member functions are normally shared by all objects of the class.
Access specifiers:
private: Members can normally be accessed only by member functions and friends of the class.public: Members can be accessed wherever the object is visible.protected: Members can be accessed by the class, its friends, and derived classes.
Example:
class Student {
private:
int rollNumber;
public:
void setRollNumber(int value) {
rollNumber = value;
}
int getRollNumber() const {
return rollNumber;
}
};
Student s1;Here, Student is a class and s1 is an object. Direct access to rollNumber is prevented, which demonstrates data hiding.
Describe how member functions are defined inside and outside a C++ class. Illustrate your answer with a program.
A member function may be defined directly inside the class body or separately outside the class.
- A function defined inside a class is implicitly considered for inline expansion.
- A function defined outside the class must use the scope-resolution operator
::. - The function declaration must still appear inside the class.
Example:
#include <iostream>
class Rectangle {
private:
double length;
double width;
public:
void setDimensions(double l, double w) { // Inside definition
length = l;
width = w;
}
double area() const; // Declaration
};
double Rectangle::area() const { // Outside definition
return length * width;
}
int main() {
Rectangle r;
r.setDimensions(5.0, 3.0);
std::cout << "Area = " << r.area();
return 0;
}Rectangle::area() indicates that area() belongs to Rectangle. Both inside and outside definitions have access to the private members of the class.
Distinguish between a structure and a union in C++. Include their memory behavior and typical uses.
Structures and unions are user-defined types that can contain members of different data types, but they manage memory differently.
| Feature | Structure | Union |
|---|---|---|
| Memory allocation | Separate storage is allocated for every member | All members share the same storage |
| Size | Approximately the sum of member sizes plus padding | At least the size of its largest member plus possible padding |
| Simultaneous values | All members can hold valid values at the same time | Normally only the most recently written member is meaningful |
| Member addresses | Members generally have different offsets | Members begin at the same memory address |
| Typical use | Representing a record with multiple fields | Saving memory or representing one of several alternatives |
Example:
struct Record {
int id;
double marks;
};
union Data {
int number;
float decimal;
char symbol;
};A Record object stores both id and marks. A Data object reuses the same memory for number, decimal, and symbol. Reading an inactive union member may produce invalid or implementation-dependent results, so unions must be used carefully.
What is an enumeration in C++? Compare unscoped enumerations with scoped enumeration classes.
An enumeration defines a user-defined type consisting of a fixed set of named integral constants. It makes code more readable by replacing unexplained numeric values with meaningful names.
Unscoped enumeration:
enum Color { Red, Green, Blue };
Color c = Red;Its enumerator names enter the surrounding scope and may be implicitly converted to integers.
Scoped enumeration:
enum class Status { Pending, Approved, Rejected };
Status s = Status::Approved;Differences:
enum classkeeps enumerators within the enumeration's scope.- Enumerators are accessed as
Status::Approved. - Scoped enumerations do not implicitly convert to
int. - Scoped enumerations reduce naming conflicts and provide stronger type safety.
- An underlying type may be specified, such as
enum class Status : unsigned char.
Therefore, enum class is generally preferred in modern C++ unless compatibility with an unscoped enumeration is required.
Explain static data members of a class. How are they declared, defined, and accessed?
A static data member belongs to the class as a whole rather than to an individual object.
Characteristics:
- Only one shared copy exists for the class.
- It can be used to store information common to all objects.
- Its lifetime normally extends throughout the execution of the program.
- It can be accessed using
ClassName::memberwhen access control permits.
Example:
#include <iostream>
class Employee {
private:
static int count;
public:
Employee() {
++count;
}
static int getCount() {
return count;
}
};
int Employee::count = 0;
int main() {
Employee e1, e2, e3;
std::cout << Employee::getCount();
}count is declared inside the class and defined outside it using the scope-resolution operator. After three objects are constructed, its value is 3. In modern C++, an inline static data member can be initialized directly in the class definition.
What is a static member function? State its properties and limitations.
A static member function is associated with a class rather than with a particular object. It is declared using the static keyword.
Properties:
- It can be called through the class name, such as
Counter::getCount(). - It may also be called through an object, although class-name syntax is clearer.
- It has no
thispointer because it is not invoked for a specific object. - It can directly access only static data members and other static member functions.
- It obeys the access-control rules of the class.
Example:
class Counter {
private:
inline static int count = 0;
public:
Counter() {
++count;
}
static int getCount() {
return count;
}
};A static member function cannot directly access a non-static member because no particular object is available. If an object is supplied explicitly as a parameter, the function may access that object's public interface.
Explain user-defined functions in C++. Describe function declaration, definition, call, parameters, and return value.
A user-defined function is a named block of code written by the programmer to perform a specific task. Functions improve modularity, reuse, testing, and readability.
Main components:
- Declaration or prototype: Informs the compiler about the function's name, return type, and parameter types.
- Definition: Contains the actual function body.
- Function call: Transfers control to the function.
- Parameters: Receive values or references supplied by the caller.
- Return value: Sends a result back to the caller.
Example:
int maximum(int, int); // Declaration
int main() {
int result = maximum(10, 25); // Call
return 0;
}
int maximum(int a, int b) { // Definition
return (a > b) ? a : b;
}The values in the call are arguments, while a and b in the definition are formal parameters. A function returning no value uses the return type void. The declaration and definition must have compatible signatures.
Define an inline function. Discuss its advantages, limitations, and difference from a preprocessor macro.
An inline function is a function for which the compiler is requested to substitute the function body at the call site. It can be declared with the inline keyword.
inline int square(int x) {
return x * x;
}Advantages:
- It may eliminate function-call overhead for small, frequently called functions.
- It retains normal C++ type checking.
- Arguments are evaluated according to ordinary function-call rules.
- It is safer and easier to debug than a macro.
Limitations:
inlineis only a request; the compiler may ignore it.- Large inline functions can increase executable size.
- Recursive, complex, or virtual calls may not be expanded at the call site.
- Modern compilers may inline functions even without the keyword.
Unlike a macro such as #define SQUARE(x) ((x) * (x)), an inline function is processed by the compiler, has a real scope and return type, and avoids repeated or unsafe evaluation of arguments.
What is a friend function in C++? Explain its declaration, use, and effect on encapsulation.
A friend function is a non-member function that is permitted to access the private and protected members of a class. It is declared inside the class using the friend keyword but is defined and called like an ordinary function.
Example:
#include <iostream>
class Box {
private:
double width;
public:
Box(double w) : width(w) {}
friend double addWidths(const Box&, const Box&);
};
double addWidths(const Box& a, const Box& b) {
return a.width + b.width;
}Important points:
- A friend function is not a member of the class.
- It has no
thispointer. - It is called as
addWidths(a, b), not asa.addWidths(b). - Friendship is granted explicitly by the class.
- Friendship is neither automatically inherited nor automatically transitive.
Friend functions are useful for symmetric operations involving multiple objects, including certain operator overloads. However, excessive friendship weakens data hiding and should be avoided.
Explain the concept of a friend class. How does it differ from a friend function?
A friend class is a class whose member functions are allowed to access the private and protected members of another class.
Example:
class Inspector;
class Machine {
private:
int secretCode = 1234;
friend class Inspector;
};
class Inspector {
public:
int readCode(const Machine& m) const {
return m.secretCode;
}
};Here, every member function of Inspector may access the private and protected members of Machine.
Friend class versus friend function:
- A friend function grants access to one specified non-member function.
- A friend class grants access to all member functions of the named class.
- Friend-class access is broader and should therefore be used more cautiously.
Rules of friendship:
- Friendship is not mutual unless both classes declare it.
- Friendship is not transitive.
- Friendship is not inherited automatically.
- A forward declaration may be needed when the friend class is declared later.
Define a reference variable in C++. Explain its initialization, uses, and important restrictions.
A reference variable is an alias for an existing object. It is declared by placing & with the reference type.
int value = 10;
int& ref = value;
ref = 25;After the assignment through ref, value also becomes 25 because both names identify the same object.
Important properties:
- A reference must normally be initialized when declared.
- An ordinary lvalue reference cannot be made to refer to another object later.
- Access through a reference uses normal variable syntax; explicit dereferencing is unnecessary.
- There are no null references in normal, valid C++ usage.
- A
constreference can refer to a constant or temporary value and prevents modification through that reference.
Uses:
- Implementing call by reference.
- Avoiding copies of large objects.
- Returning an existing object from a function.
- Creating readable aliases.
A reference should not be returned if it refers to a local automatic variable, because that variable is destroyed when the function finishes.
Differentiate among call by value, call by address, and call by reference in C++.
The three techniques differ in what is passed to the function and whether the original argument can be modified.
| Technique | Parameter form | What is passed | Original can be modified? |
|---|---|---|---|
| Call by value | void f(int x) |
A copy of the value | No |
| Call by address | void f(int* x) |
The object's address | Yes, through *x |
| Call by reference | void f(int& x) |
An alias to the object | Yes, directly |
Examples:
void byValue(int x) {
++x;
}
void byAddress(int* x) {
if (x != nullptr) {
++(*x);
}
}
void byReference(int& x) {
++x;
}Calls:
byValue(a);
byAddress(&a);
byReference(a);Call by value provides isolation but may copy an object. Call by address supports null pointers and pointer arithmetic but requires explicit dereferencing. Call by reference provides simpler syntax and generally requires a valid object. For efficient read-only access to a large object, const Type& is commonly used.
Write and explain C++ functions that swap two integers using call by value, call by address, and call by reference.
Program:
#include <utility>
void swapValue(int a, int b) {
int temp = a;
a = b;
b = temp;
}
void swapAddress(int* a, int* b) {
if (a != nullptr && b != nullptr) {
int temp = *a;
*a = *b;
*b = temp;
}
}
void swapReference(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}If x = 10 and y = 20:
swapValue(x, y)swaps only the local copies. The caller's variables remain unchanged.swapAddress(&x, &y)passes addresses and modifiesxandythrough dereferencing.swapReference(x, y)makesaandbaliases ofxandy, so the caller's variables are modified directly.
Call by address requires null checks when null pointers are possible. Call by reference has cleaner syntax and is generally preferred when the parameters must always identify valid objects.
Define recursion. Explain the base case, recursive case, and role of the call stack.
Recursion is a technique in which a function solves a problem by calling itself with a smaller or simpler input.
A correct recursive function requires:
- Base case: A condition that returns a result without making another recursive call.
- Recursive case: A step that reduces the original problem and invokes the same function.
- Progress toward termination: Every recursive call must move closer to the base case.
During recursion, each function call creates an activation record or stack frame. It normally stores parameters, local variables, and the return address. Frames are removed in reverse order when calls return.
Example:
int sum(int n) {
if (n <= 0) {
return 0;
}
return n + sum(n - 1);
}For positive , the mathematical relationship is:
If the base case is missing or unreachable, recursion may continue until stack space is exhausted, causing stack overflow.
Develop a recursive C++ function to calculate factorial and trace its execution for .
For a non-negative integer , factorial is defined as:
The recursive definition is:
C++ function:
unsigned long long factorial(unsigned int n) {
if (n == 0) {
return 1;
}
return n * factorial(n - 1);
}Trace for :
factorial(5)returns5 * factorial(4).factorial(4)returns4 * factorial(3).factorial(3)returns3 * factorial(2).factorial(2)returns2 * factorial(1).factorial(1)returns1 * factorial(0).factorial(0)returns1.
During unwinding:
The function has time complexity and stack-space complexity . Even unsigned long long overflows for sufficiently large values of .
Compare recursion and iteration. State the advantages and disadvantages of each technique.
Recursion repeats work by making function calls, while iteration repeats work using loops such as for, while, or do-while.
| Aspect | Recursion | Iteration |
|---|---|---|
| Control mechanism | Repeated function calls | Loops |
| Termination | Base case | Loop condition |
| Memory | Uses call-stack frames | Usually uses constant extra stack space |
| Overhead | Function-call overhead | Usually lower overhead |
| Readability | Elegant for naturally recursive problems | Clear for simple repetitive tasks |
| Failure risk | Stack overflow if recursion is too deep | Infinite loop if condition never becomes false |
Advantages of recursion:
- Closely matches recursive mathematical definitions.
- Useful for trees, divide-and-conquer algorithms, backtracking, and directory traversal.
- Can produce concise solutions.
Advantages of iteration:
- Usually faster and more memory-efficient.
- Better for very large repetition counts.
- Avoids call-stack depth limitations.
The choice depends on clarity, input size, performance requirements, and the natural structure of the problem.
Describe formatted input/output and stream-state handling in C++.
C++ supports formatted input/output through stream member functions and manipulators, many of which are available in <iomanip>.
Common manipulators:
std::setw(n): Sets the minimum width of the next output field.std::setprecision(n): Controls floating-point precision.std::fixed: Uses fixed-point notation.std::scientific: Uses scientific notation.std::leftandstd::right: Control alignment.std::boolalpha: Displays Boolean values astrueorfalse.
Example:
#include <iomanip>
#include <iostream>
int main() {
double value = 12.34567;
std::cout << std::fixed << std::setprecision(2) << value;
}This displays 12.35.
Stream-state functions:
good(): No error state is set.fail(): A formatting or extraction operation failed.bad(): A serious input/output error occurred.eof(): End-of-file was encountered.clear(): Resets stream error flags.ignore(): Discards unwanted characters.
Input should be validated with a condition such as if (std::cin >> value). After invalid input, the stream can be recovered using clear() followed by ignore().
Design a C++ class that demonstrates classes and objects, an enumeration class, a static data member, a static member function, a friend function, and reference parameters. Explain the design.
Illustrative design:
#include <iostream>
#include <string>
enum class Result { Pass, Fail };
class Student {
private:
std::string name;
int marks;
inline static int objectCount = 0;
public:
Student(const std::string& n, int m) : name(n), marks(m) {
++objectCount;
}
Result getResult() const {
return marks >= 40 ? Result::Pass : Result::Fail;
}
void addGraceMarks(const int& grace) {
marks += grace;
}
static int getObjectCount() {
return objectCount;
}
friend void display(const Student& student);
};
void display(const Student& student) {
std::cout << student.name << " " << student.marks;
}Explanation:
Studentencapsulatesnameandmarksas private data.- Each
Studentobject has separate values for its non-static members. Resultis a scoped enumeration that provides type-safe result values.objectCountis shared by all objects.getObjectCount()is static and can be called asStudent::getObjectCount().display()is a friend function, so it can read private members.const std::string&andconst int&avoid copying and prevent modification through the parameters.
In production code, object counting may also require a copy constructor and destructor, depending on whether the count represents current live objects or total constructions.
Compare the procedural programming paradigm with the object-oriented programming paradigm.
Procedural programming organizes a program around functions or procedures, whereas object-oriented programming (OOP) organizes it around objects that combine data and behavior.
| Basis | Procedural Programming | Object-Oriented Programming |
|---|---|---|
| Primary unit | Function or procedure | Class and object |
| Approach | Top-down | Bottom-up |
| Data handling | Data is often shared among functions | Data is encapsulated within objects |
| Security | Limited data hiding | Supports data hiding through access specifiers |
| Reusability | Mainly through functions | Through inheritance, composition, and polymorphism |
| Maintenance | Difficult for large programs | Easier because the system is divided into classes |
| Examples | C, Pascal | C++, Java, C# |
Major principles of OOP:
- Encapsulation: Bundling data and functions in a class.
- Abstraction: Showing essential features while hiding implementation details.
- Inheritance: Creating a new class from an existing class.
- Polymorphism: Allowing one interface to represent multiple implementations.
OOP is generally preferred for large and complex software because it improves modularity, maintainability, security, and code reuse.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →