UNIT 4: Object-Oriented Programming & Methodology - Short Notes
1. Introduction to Object-Oriented Programming
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects," which are instances of classes containing data (attributes) and code (methods).
Core Features (4 Pillars):
-
Encapsulation: Bundling data and methods that operate on that data within a single unit (class), restricting direct access to some components.
-
Abstraction: Hiding implementation details and showing only essential features of an object.
-
Inheritance: Mechanism where a new class (derived/child) acquires properties and behaviors of an existing class (base/parent).
-
Polymorphism: Ability of an object to take many forms. Commonly achieved through function overloading (compile-time) and virtual functions (run-time).
Advantages over Procedural Programming:
-
Modularity: Code is organized into self-contained classes.
-
Reusability: Inheritance allows reuse of existing code.
-
Data Hiding: Protects data from accidental modification.
-
Easy Maintenance & Debugging: Problems are localized to specific objects/classes.
-
Scalability: Easier to manage and extend large, complex systems.
[!TIP] Exam Focus: Be prepared to contrast Encapsulation (bundling) vs Information Hiding (restricting access via
private/protected). OOP techniques for complexity management include modularity, abstraction, and hierarchical classification (inheritance).
2. C++ Fundamentals and Differences from C
| Feature | C | C++ |
|---|---|---|
| Paradigm | Procedural | Multi-paradigm (Procedural + OOP) |
| Core Concept | Functions & Structures | Classes & Objects |
| Data Security | No access control | Access Specifiers (public, private, protected) |
| I/O | printf(), scanf() |
cin, cout (stream-based) |
| Functions | Only global/static | Member functions, function overloading |
| Memory | malloc(), calloc(), free() |
new, delete operators |
| Other | No constructors/destructors, no inheritance, no templates | Has constructors, destructors, inheritance, templates, exception handling |
Structure vs Class:
-
struct: Default access ispublic. Primarily used for passive data structures. -
class: Default access isprivate. Used for active objects with encapsulation.
Variable Declaration Scope:
-
Significance: Variables can be declared exactly where they are needed (e.g., inside a loop, within a block
{ }). -
Benefit: Improves readability, prevents unintended use, and allows for automatic destruction when the scope ends (RAII principle).
Call by Reference & Return by Reference:
// Call by Reference (modifies original)
void swap(int &a, int &b) { int t=a; a=b; b=t; }
// Return by Reference (efficient, avoids copy)
int &max(int &a, int &b) { return (a>b)? a : b; } // Returns alias
3. Classes and Objects in C++
Class Definition: A blueprint for objects.
class ClassName {
private: // Hidden data
int data;
public: // Interface
void setData(int d) { data = d; }
};
Object Instantiation: ClassName objName;
Access Specifiers:
-
public: Accessible from anywhere. -
private: Accessible only within the class. -
protected: Accessible within the class and its derived classes.
Accessing Members:
-
Inside
main(): Use object name and dot operator:obj.setData(10); -
Inside member function of same class: Direct access by name:
data = d; -
Inside member function of another class:
-
Via public interface of the object:
obj.setData(10); -
Via
friendfunction/class. -
Via inheritance (if base class member is
protected/public).
-
Constructors:
-
Special member function with same name as class, no return type.
-
Types:
-
Default Constructor:
ClassName() {}(no args or all args have defaults). -
Parameterized Constructor:
ClassName(int x) { ... } -
Copy Constructor:
ClassName(const ClassName &obj) { ... }// Deep copy often needed.
-
-
Constructor Overloading: Multiple constructors with different parameters.
-
Delegating Constructor (C++11): One constructor calls another:
ClassName(int x) : ClassName() { ... } -
Order of Calls (Inheritance): Base class constructor is called first, then derived class constructor.
Destructor:
-
~ClassName() { ... } -
Called automatically when object goes out of scope.
-
Order of Calls (Inheritance): Derived class destructor body executes first, then base class destructor.
Array of Objects:
ClassName objArray[3]; // Creates 3 default-constructed objects
objArray[0].setData(10);
Dynamic Allocation of Object Arrays:
ClassName *ptr = new ClassName[3]; // Array of 3 objects
delete[] ptr; // MUST use delete[] for arrays
4. Inheritance
Concept: Creating new classes (derived) from existing ones (base), promoting code reuse and hierarchical classification.
Types of Inheritance:
| Type | Description | Example |
|---|---|---|
| Single | One derived from one base. | class Derived : public Base |
| Multiple | One derived from multiple bases. | class D : public B1, public B2 |
| Multilevel | Chain of inheritance. | A -> B -> C |
| Hierarchical | One base, multiple derived. | B1, B2 : public A |
| Hybrid | Combination of two or more types. | (e.g., Hierarchical + Multiple) |
Multiple Inheritance - Diamond Problem:
-
Occurs when a class
Dinherits fromB1andB2, which both inherit fromA.Dgets two copies ofA's members, causing ambiguity. -
Resolution: Virtual Inheritance (
class B1 : virtual public A). Ensures only one shared subobject ofAexists inD.
Access Specifiers in Inheritance:
| Base Member | public Inheritance |
protected Inheritance |
private Inheritance |
|---|---|---|---|
public |
public |
protected |
private |
protected |
protected |
protected |
private |
private |
Inaccessible | Inaccessible | Inaccessible |
Base Constructor Invocation:
-
Base constructor is called automatically before derived constructor.
-
Explicit call:
Derived(int x) : Base(x) { ... }// Initializer list.
Order Summary (Object Creation/Destruction):
-
Creation: Base Constructor โ Derived Constructor.
-
Destruction: Derived Destructor โ Base Destructor.
\boxed{\text{Order: Base \rightarrow Derived (Construction), Derived \rightarrow Base (Destruction)}}
5. Polymorphism
Definition: "Many forms." Ability to present same interface for different underlying forms (data types/classes).
Compile-Time (Static) Polymorphism:
-
Achieved by function overloading and operator overloading.
-
Function Overloading: Multiple functions with same name but different parameters (type/number).
int Max(int a, int b); float Max(float a, float b); string Max(string a, string b); -
Operator Overloading: Redefining operator for user-defined types.
Complex operator+(const Complex& c) { return Complex(real + c.real, imag + c.imag); }-
Unary:
++obj,-obj(1 operand). -
Binary:
obj1 + obj2(2 operands).
-
-
Pros: Intuitive syntax. Cons: Can reduce readability if misused.
Run-Time (Dynamic) Polymorphism:
-
Achieved by virtual functions and inheritance.
-
Virtual Function: Declared with
virtualin base class. Resolved at run-time based on object type (dynamic binding). -
vtable (Virtual Table): Hidden table per class containing addresses of virtual functions. Object has a hidden
vptrpointing to its class's vtable. -
Pure Virtual Function & Abstract Class:
class Shape { public: virtual float area() = 0; // Pure virtual (no body) };-
Class with at least one pure virtual function is abstract.
-
Cannot instantiate abstract class objects.
-
Derived classes must override pure virtual functions to become concrete.
-
Overloading vs Overriding:
| Feature | Overloading | Overriding |
|---|---|---|
| Definition | Same function name, different parameters in same scope. | Redefining base class's virtual function in derived class with same signature. |
| Polymorphism | Compile-time | Run-time |
| Scope | Same class or different functions in same scope. | Base and derived classes. |
| Keyword | Not required. | virtual in base, optional override in derived (C++11). |
Binding:
-
Early (Static) Binding: Function call resolved at compile-time (e.g., overloaded functions, non-virtual functions).
-
Late (Dynamic) Binding: Function call resolved at run-time using vtable (e.g., virtual functions).
6. Advanced C++ Features
Friend Function:
-
Not a member of the class but granted access to private/protected members.
-
Declared with
friendinside class. -
Use: Operator overloading (for symmetry), utility functions needing direct access.
class Box { private: int len; friend void showLen(Box); // Friend function declaration };
Friend Class:
-
Entire class is granted access to private/protected members of another class.
-
class B { friend class A; };//Acan accessB's private members.
Static Members:
-
Static Variable: Shared by all objects of the class. Declared in class, defined outside.
class Counter { public: static int count; }; int Counter::count = 0; // Definition -
Static Member Function: Can access only static members. Called using class name:
ClassName::func();
Inline Functions:
-
Request to compiler to insert function body at call site (avoids function call overhead).
-
inline int max(int a, int b) { return (a>b)?a:b; } -
vs Macros: Inline functions are type-safe, respect scope, and are debugged by compiler. Macros are simple text substitution, error-prone.
this Pointer:
-
Implicit pointer passed to all non-static member functions.
-
Points to the object for which the function is called.
-
Used to:
-
Distinguish member variables from parameters:
this->x = x; -
Return the current object:
return *this;
-
7. Templates
Function Templates: Generic programming. Single function works for multiple data types.
template <typename T>
T Max(T a, T b) {
return (a > b) ? a : b;
}
// Usage: Max(10, 20), Max(3.14, 2.71), Max('a', 'z')
Overloaded Function Templates:
-
Can have multiple function templates with same name but different template parameters or constraints.
-
Exact match is preferred over template deduction during overload resolution.
8. Memory Management
Dynamic Allocation:
-
Single Object:
ClassName *ptr = new ClassName(args); -
Array:
ClassName *arr = new ClassName[n]; -
Deallocation:
-
Single:
delete ptr; -
Array:
delete[] arr;// CRITICAL: Must matchnew[].
-
Memory Leaks:
-
Occurs when dynamically allocated memory is not deallocated (
delete/delete[]not called). -
Best Practices:
-
Pair every
newwithdelete. -
Use RAII (Resource Acquisition Is Initialization): Wrap resources in objects whose destructors free them (e.g.,
std::unique_ptr,std::vector). -
Set pointer to
nullptrafter deletion.
-
9. Exception Handling
Mechanism: Handling run-time errors (exceptions) gracefully without terminating program.
Keywords:
-
try: Block containing code that might throw an exception. -
catch: Block to handle the exception of a specific type. -
throw: Used to signal an exception (throw an object/expression).
Structure:
try {
// Risky code
if (error) throw "Error message"; // or throw exception_obj;
}
catch (const char* e) { // Catch specific type
cout << "Caught: " << e << endl;
}
catch (...) { // Catch-all (any exception type)
cout << "Unknown exception!" << endl;
}
Synchronous vs Asynchronous Exceptions:
| Synchronous | Asynchronous | |
|---|---|---|
| Cause | Directly caused by program statement (e.g., divide by zero, new failure). |
Caused by external events (e.g., keyboard interrupt, hardware failure). |
| Handling in C++ | Yes, via try/catch. |
No, C++ standard does not handle these. |
Exception Propagation:
-
If an exception is not caught in the current
tryblock, it propagates up the call stack to the next enclosingtryblock. -
If no handler found, program calls
terminate().
10. Input/Output and Debugging
Standard I/O:
-
cin(console input),cout(console output). Uses<<(insertion) and>>(extraction) operators.int x; cout << "Enter: "; cin >> x;
File I/O:
-
#include <fstream> -
ofstream(output file stream): Write to file. -
ifstream(input file stream): Read from file. -
fstream(both).ofstream fout("file.txt"); fout << "Data"; fout.close();
Debugging Pointers - Common Issues:
| Issue | Description | Prevention |
|---|---|---|
| Dangling Pointer | Pointer points to deleted/invalid memory. | Set pointer to nullptr after delete. |
| Memory Leak | Allocated memory never freed. | Always delete/delete[]. Use smart pointers (unique_ptr). |
| Null Pointer Dereference | Accessing memory via nullptr. |
Check if (ptr != nullptr) before dereferencing. |
| Array Out-of-Bounds | Accessing beyond allocated array. | Use std::vector with .at() (bounds-checked) or careful index management. |
11. Practical Case Studies and Programs (Key Examples)
1. Complex Number Class (Operator Overloading):
class Complex {
float real, imag;
public:
Complex(float r=0, float i=0): real(r), imag(i) {}
Complex operator+(const Complex& c) {
return Complex(real + c.real, imag + c.imag);
}
Complex operator-(const Complex& c) {
return Complex(real - c.real, imag - c.imag);
}
Complex operator*(const Complex& c) {
return Complex(real*c.real - imag*c.imag,
real*c.imag + imag*c.real);
}
void display() { cout << real << " + i" << imag; }
};
2. Employee Record System (Inheritance, Constructors):
class Person {
string name;
public:
Person(string n) : name(n) {}
// ... other methods
};
class Employee : public Person {
double salary;
int year;
string insuranceNo;
public:
// Base class constructor MUST be called explicitly if no default.
Employee(string n, double s, int y, string ins)
: Person(n), salary(s), year(y), insuranceNo(ins) {}
// ... accessor methods, equals(), etc.
};
3. Grade Calculation Program (Class Design):
class Student {
int marks[3];
public:
void setMarks(int m1, int m2, int m3) {
marks[0]=m1; marks[1]=m2; marks[2]=m3;
}
int getMarks(int i) { return marks[i]; }
void getResults() {
float avg = (marks[0]+marks[1]+marks[2])/3.0;
if(avg>=80) cout<<"A";
else if(avg>=65) cout<<"B";
// ... other grades
}
};
4. Validation of Examination Marks (Method in Class):
class Student {
int marks;
public:
void setMarks(int m) {
if(m < 65 || m > 100) {
throw "Invalid Marks! Must be 65-100.";
}
marks = m;
}
};
// Usage in main:
try {
s.setMarks(50); // Throws exception
}
catch (const char* e) {
cout << e << endl;
}
5. Fee Calculation based on Branch (Array of Objects):
class Student {
int branchId;
float fees;
public:
void setBranch(int id) { branchId = id; }
void calcFees() {
// Use switch or array to set fees based on branchId
float feeTable[] = {50000, 75000, 60000}; // Example
fees = feeTable[branchId];
}
};
int main() {
Student s[3];
for(int i=0; i<3; i++) {
s[i].setBranch(i); // Assume branchId 0,1,2
s[i].calcFees();
}
}
6. Survey Operator Class (Derived from Person, Friendship):
-
Key Point: If
Personhas no default constructor, derived class constructor must explicitly call a base constructor in initializer list. -
MakeCallmethod might usefriendfunctions for certain operations if needed.
[!TIP] Exam Focus: For case study questions, structure your program clearly: define base/derived classes, use appropriate constructors (especially explicit base call), implement required methods, and show a simple
main()demonstrating usage. Pay attention to access specifiers (protectedfor base data often used in inheritance).