UNIT 1: OBJECT-ORIENTED PROGRAMMING & C++ FUNDAMENTALS
A. FOUNDATIONS OF OOP & C++ OVERVIEW
Core OOP Concepts & Paradigm Advantages
-
Definition: OOP is a programming paradigm that organizes software design around objects (data) and methods (functions) rather than functions and logic.
-
Need: To manage complexity of large software systems by modeling real-world entities.
-
Unique Advantages vs. Procedural Programming:
-
Modularity: Code is organized into self-contained classes.
-
Reusability: Inheritance allows reuse of existing code.
-
Data Hiding: Protects internal data from accidental modification.
-
Easy Maintenance & Debugging: Objects are independent; changes are localized.
-
Flexibility: Polymorphism provides a uniform interface.
-
-
Core Concepts:
-
Object: A runtime instance of a class.
-
Class: A blueprint/template for creating objects.
-
Abstraction: Hiding implementation details, showing only essential features.
-
Encapsulation: Bundling data and methods that operate on that data within a single unit (class).
-
Inheritance: Mechanism where a new class (derived) acquires properties of an existing class (base).
-
Polymorphism: Ability of an object to take many forms (compile-time & run-time).
-
-
Handling System Complexity: OOP uses abstraction to break down a complex system into manageable objects with well-defined interfaces.
C++ as an Object-Oriented Language
-
Key Extensions over C:
-
Classes & Objects
-
Constructors/Destructors
-
Inheritance & Polymorphism
-
Function/Operator Overloading
-
Templates
-
Exception Handling
-
cin/coutI/O streams
-
-
Structure of a C++ Program:
#include <iostream> // Header file using namespace std; // Namespace (optional but common) class MyClass { /*...*/ }; // Class definition int main() { // Entry point // Program logic return 0; } -
Significance of Variable Declaration Anywhere: Unlike C (declarations only at block start), C++ allows declaration close to point of use, improving readability and enabling initialization at declaration.
-
I/O:
cin/coutvs.scanf/printf:-
cin/cout: Type-safe, use<</>>operators, object-oriented (part ofiostreamlibrary). -
scanf/printf: C-style, format-string based, not type-safe, faster for simple I/O.
-
Data Encapsulation & Information Hiding
| Feature | Data Encapsulation | Information Hiding |
|---|---|---|
| Definition | Bundling data & related functions into a single unit (class). | Hiding internal implementation details and protecting data from direct external access. |
| Goal | Organization & modularity. | Security & controlled access. |
| Mechanism | Achieved using access specifiers (private, public, protected). |
Primarily achieved by declaring data members as private and providing public getter/setter methods. |
| Analogy | A capsule containing medicine (data) and coating (functions). | The coating hides the medicine's exact composition. |
[!TIP] Exam Focus: Often asked as "difference between". Emphasize that encapsulation is the technique, information hiding is the principle achieved through encapsulation.
B. CLASSES, OBJECTS & MEMBER ACCESS
Class & Object Fundamentals
-
Defining a Class:
class Rectangle { private: // Access specifier double length, width; // Data members public: void setDimensions(double l, double w); // Member function declaration double area(); // Member function declaration }; -
Creating Objects:
Rectangle rect1;(Stack) orRectangle* rect2 = new Rectangle();(Heap). -
Access Mechanism:
-
Inside
main():-
Use dot operator (
.) for object:rect1.setDimensions(5, 3); -
Use arrow operator (
->) for pointer:rect2->setDimensions(5, 3);
-
-
Inside a member function of the same class: Direct access by name.
length = l; -
Inside a member function of another class: Not allowed unless the other class is a
friendor the member ispublic.
-
Array of Objects & Dynamic Object Creation
-
Array of Objects: Contiguous block of objects.
Rectangle arr[3]; // Array of 3 Rectangle objects arr[0].setDimensions(1,2); -
Dynamic Array with Pointers:
int n = 5; Rectangle* objArr = new Rectangle[n]; // Allocate array on heap objArr[0].setDimensions(...); delete[] objArr; // Must deallocate -
Pointer to Object & Arrow Operator:
Rectangle* ptr = &rect1; ptr->area();is equivalent to(*ptr).area();.
[!TIP] Common Pitfall: Forgetting
delete[]for dynamically allocated arrays causes memory leaks. Usedeletefor single object,delete[]for array.
C. CONSTRUCTORS & DESTRUCTORS
Constructor Fundamentals
-
Definition: Special member function with same name as class, no return type, invoked automatically during object creation.
-
Purpose: Initialize data members, allocate resources.
-
Types:
-
Default Constructor: Takes no arguments. Can be user-defined or compiler-generated (if no other constructor exists).
-
Parameterized Constructor: Takes arguments for initialization.
-
-
Constructor Overloading: Multiple constructors with different parameter lists.
class Box { double side; public: Box() { side = 1; } // Default Box(double s) { side = s; } // Parameterized }; -
Constructor Chaining: Calling one constructor from another using member initializer list.
Box::Box() : Box(1.0) { } // Delegates to parameterized constructor
Special Constructors
-
Copy Constructor:
-
Definition: Constructor that takes a reference to an object of the same class as its parameter.
-
Purpose: Create a new object as a copy of an existing object. Crucial for pass-by-value, return-by-value.
-
Syntax:
ClassName(const ClassName& obj); -
Example:
class Sample { int* data; public: Sample(const Sample& orig) { // Deep copy recommended data = new int(*orig.data); } };
-
-
Constructor for Derived Class: Base class members must be initialized before derived class members. Use member initializer list to explicitly call base constructor.
class Derived : public Base { int x; public: Derived(int a, int b) : Base(a), x(b) { } // Base(a) initializes base part };
Destructor
-
Definition: Special member function with ~ClassName, no parameters, no return type. Called automatically when object goes out of scope or is
deleted. -
Purpose: Clean up resources (free memory, close files).
-
Order of Calls:
-
Construction: Base class constructor → Derived class constructor.
-
Destruction: Derived class destructor → Base class destructor.
\boxed{\text{Order: Base \rightarrow Derived (Construction), Derived \rightarrow Base (Destruction)}}
-
D. STRUCTURE vs. CLASS
| Feature | struct |
class |
|---|---|---|
| Default Access | public |
private |
| Default Inheritance | public |
private |
| Primary Use | Passive data structures (POD - Plain Old Data). | Active objects with encapsulation and polymorphism. |
| Polymorphism | Can have virtual functions, but less common. | Primary tool for implementing polymorphism. |
| Example | struct Point { int x, y; }; |
class Point { private: int x, y; public: ... }; |
Illustrative Program:
struct S {
int a; // public by default
};
class C {
int a; // private by default
public:
void setA(int x) { a = x; }
};
int main() {
S s; s.a = 10; // OK
C c; // c.a = 10; // ERROR: 'a' is private
c.setA(10); // OK
}
E. ACCESS CONTROL & FRIEND FUNCTIONS
Access Specifiers in Depth
| Specifier | Access within class | Access from derived class | Access from outside world |
|---|---|---|---|
private |
Yes | No | No |
protected |
Yes | Yes | No |
public |
Yes | Yes | Yes |
-
Inheritance: Access specifier in the inheritance clause (
public,private,protected) controls how base class members are inherited by the derived class.-
publicinheritance:public→public,protected→protected,private→inaccessible. -
privateinheritance: All becomeprivatein derived.
-
Friend Mechanism
-
Friend Function:
-
Definition: Non-member function granted full access to private/protected members of a class.
-
Syntax: Declared inside class with keyword
friend. -
Application: When two unrelated classes need to share data, or for operator overloading of
<</>>.
class Box { double width; public: friend void setWidth(Box& b, double w); // Declaration }; void setWidth(Box& b, double w) { b.width = w; } // Definition (no `friend` keyword) -
-
Friend Class: Entire class is granted access.
class Helper; // Forward declaration class Box { friend class Helper; // All Helper's member functions can access Box's private members };
[!TIP] Caution: Friendship is not transitive (A friend of B is not automatically friend of B's friends) and not inherited.
F. INHERITANCE
Inheritance Fundamentals
-
Definition: Mechanism to create a new class (derived/child) from an existing class (base/parent).
-
Importance: Code reuse, extensibility, logical hierarchy.
-
Types:
-
Single: One base → one derived.
-
Multilevel: Base → Intermediate → Derived.
-
Multiple: One derived → multiple bases. (Can cause diamond problem).
-
Hierarchical: One base → multiple derived.
-
Hybrid: Combination of above.
-
Program Examples:
-
Multiple Inheritance:
class A { public: void fA() {} }; class B { public: void fB() {} }; class C : public A, public B { }; // C inherits from A and B
Complexity in Multiple Inheritance
-
Ambiguity: If two base classes have members with same name, the derived class object has two copies. Access becomes ambiguous.
class Base1 { public: int x; }; class Base2 { public: int x; }; // Same name class Derived : public Base1, public Base2 {}; Derived d; d.x = 5; // ERROR: Which x? d.Base1::x or d.Base2::x? -
Diamond Problem: A form of ambiguity where a class inherits from two classes that themselves inherit from a common base, leading to two copies of the base subobject.
class Grand { public: int id; }; class Parent1 : public Grand {}; class Parent2 : public Grand {}; class Child : public Parent1, public Parent2 {}; // Two 'id' members! -
Resolution: Virtual Base Classes:
class Parent1 : virtual public Grand {}; class Parent2 : virtual public Grand {}; class Child : public Parent1, public Parent2 {}; // Now only ONE shared 'Grand' subobject exists in Child.
Constructors & Inheritance
-
Order of Calls (Creation): Base class constructors (in order of inheritance declaration) → Derived class constructor.
-
Order of Calls (Destruction): Reverse of construction. Derived class destructor → Base class destructors (reverse order of construction).
-
Explicit Base Invocation:
class Derived : public Base { public: Derived(int a, int b) : Base(a) { // Explicitly calls Base(int) // Derived's initialization } };
G. POLYMORPHISM
Compile-Time Polymorphism (Static Binding)
-
Function Overloading:
-
Definition: Multiple functions with same name but different parameters (type, number, or sequence) in the same scope.
-
Rules: Return type cannot be the only difference.
-
Example:
int Max(int a, int b) { return (a>b)?a:b; } float Max(float a, float b) { return (a>b)?a:b; } string Max(string a, string b) { return (a>b)?a:b; }
-
-
Operator Overloading:
-
Definition: Redefining the behavior of an existing operator for user-defined types.
-
Rules: At least one operand must be user-defined. Cannot create new operators.
-
Example (Unary
++):class Counter { int count; public: Counter& operator++() { // Prefix ++count; return *this; } }; -
Pros: Intuitive syntax, allows operations on objects like built-in types.
-
Cons: Can reduce readability if misused, cannot change operator precedence/associativity.
-
Run-Time Polymorphism (Dynamic Binding)
-
Virtual Functions:
-
Definition: Member function declared with keyword
virtualin base class. Overridden in derived class. -
Mechanism: Late binding. Function call resolved at runtime based on actual object type, not pointer/reference type. Uses vtable (virtual table).
class Shape { public: virtual double area() { return 0; } // Virtual function }; class Rect : public Shape { double l, w; public: double area() override { return l*w; } // Override }; -
-
Pure Virtual Functions & Abstract Classes:
-
Pure Virtual:
virtual returnType func(params) = 0; -
Abstract Class: Contains at least one pure virtual function. Cannot be instantiated. Derived classes must implement pure virtual functions to become concrete.
class Shape { public: virtual double area() = 0; // Pure virtual }; // Shape s; // ERROR: Abstract class -
-
Achieving Polymorphism: Use base class pointer/reference to point to derived class object.
Shape* ptr = new Rect(); ptr->area(); // Calls Rect::area() at runtime -
Program Example (Area Calculation):
#include <iostream> using namespace std; class Shape { public: virtual double area() = 0; }; class Rect : public Shape { double l, w; public: Rect(double a, double b): l(a), w(b) {} double area() { return l*w; } }; class Circle : public Shape { double r; public: Circle(double radius): r(radius) {} double area() { return 3.14*r*r; } }; int main() { Shape* shapes[2]; shapes[0] = new Rect(4,5); shapes[1] = new Circle(3); for(int i=0; i<2; i++) cout << shapes[i]->area() << endl; // Output: 20, 28.26 }
H. FUNCTION TEMPLATES & OVERLOADING
Template Fundamentals
-
Need: Write generic code that works with any data type without code duplication.
-
Function Template Syntax:
template <typename T> // or 'class T' T Max(T a, T b) { return (a > b) ? a : b; } // Usage: Max(3, 5); Max(3.5, 2.1); Max('a', 'z');
Overloaded Function Templates
-
Concept: Provide a non-template overload for specific types when template version is not optimal or causes ambiguity.
-
Example:
template <typename T> T Max(T a, T b) { return (a>b)?a:b; } // Overload for const char* (string literals) to compare lexicographically const char* Max(const char* a, const char* b) { return (strcmp(a,b) > 0) ? a : b; }
I. MEMORY MANAGEMENT
Dynamic Memory Allocation
-
new&deleteOperators:-
Single Variable:
int* p = new int(5); delete p; -
Array:
int* arr = new int[10]; delete[] arr; -
Object:
MyClass* obj = new MyClass(); delete obj;
-
-
Program Example:
class Student { int id; public: Student(int i) : id(i) {} ~Student() { cout << "Destroying " << id << endl; } }; int main() { Student* s1 = new Student(101); Student* sArr = new Student[3]{Student(1), Student(2), Student(3)}; delete s1; delete[] sArr; return 0; }
Pointers & Debugging
-
Dangling Pointer: Pointer pointing to deallocated memory.
int* p = new int(5); delete p; *p = 10; // ERROR: p is dangling p = nullptr; // Fix after delete -
Memory Leak: Allocated memory not deallocated.
-
Relationship: Pointer → Array (pointer arithmetic) → Objects (pointer to object/array of objects).
J. EXCEPTION HANDLING
Exception Fundamentals
-
What are Exceptions?: Synchronous events (like divide-by-zero, out-of-bounds) that disrupt normal flow. (Asynchronous exceptions are external events like keyboard interrupts, not handled by C++ EH).
-
Keywords:
-
throw: Raises an exception. -
try: Block containing code that might throw. -
catch: Handler for a specific exception type.
-
-
Program Structure:
try { // Code that may throw if (denom == 0) throw "Division by zero!"; } catch (const char* msg) { // Handler for const char* cout << msg << endl; } catch (...) { // Catch-all handler cout << "Unknown exception" << endl; }
Handling Multiple Exceptions
-
Multiple
catchblocks ordered from most specific to most general. -
catch (...)must be the last catch block. -
Example:
try { /* ... */ } catch (int e) { /* Handle integer exception */ } catch (const char* s) { /* Handle string exception */ } catch (...) { /* Handle any other exception */ }
K. ADVANCED TOPICS & MISCELLANEOUS
Static Members
-
Static Data Member: Shared by all objects of the class. Declared inside class, defined/initialized outside.
class Counter { static int count; // Declaration public: Counter() { count++; } static int getCount() { return count; } }; int Counter::count = 0; // Definition & initialization -
Static Member Function: Can access only static members. Called using
ClassName::func().
Inline Functions
-
Definition: Suggest compiler to insert function body at call site (avoid function call overhead).
-
Syntax: Define inside class or use
inlinekeyword outside.class Calc { public: inline int add(int a, int b) { return a+b; } // Inline by default inside class }; -
Macros vs. Inline Functions:
| Feature | Macros (
#define) | Inline Functions | | :--- | :--- | :--- | | Type Safety | No (text substitution) | Yes (type-checked by compiler) | | Debugging | Difficult (no symbol) | Easier (function symbol exists) | | Scope | Global (preprocessor) | Respects scope (namespace/class) | | Side Effects | Multiple evaluation (e.g.,MAX(x++, y++)) | Single evaluation |
File I/O
-
File Stream Classes:
-
ifstream: Input from file. -
ofstream: Output to file. -
fstream: Both input & output.
-
-
Program Example:
#include <fstream> int main() { ofstream outFile("data.txt"); outFile << "Hello File" << endl; outFile.close(); ifstream inFile("data.txt"); string line; getline(inFile, line); cout << line << endl; // Output: Hello File inFile.close(); return 0; }
[!TIP] Exam Tip: For "publishing" an inline function, it means defining it inside the class definition (implicitly inline) or using the
inlinekeyword in its external definition.