Principles of OOP, classes and objects notes — Unit 1
Free unit-wise study notes on principles of oop, classes and objects for Object Oriented Programming with C++, Semester 2 of B.Tech — Computer Science & Engineering — key concepts, examples, important questions and a revision checklist for semester exams.
An exhaustive, deep-dive into the foundational principles of Object-Oriented Programming. This unit covers the shift from procedural thinking to the object model, memory layout of classes, access control, static members, and advanced object interactions.
Notebook — 16 pages
Page 1
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
1. Evolution of Programming Paradigms
Before we can appreciate the object-oriented model, we must understand the historical progression of programming paradigms and the exact limitations that forced the industry to evolve.
⇒Unstructured Programming
Early programming languages relied heavily on `GOTO` statements to jump between different parts of a program. This created 'spaghetti code'—a tangled mess of logic that was nearly impossible to debug, maintain, or extend. As programs grew past a few thousand lines, unstructured programming became a massive liability.
⇒Procedural Oriented Programming (POP)
To solve the spaghetti code problem, POP (used by languages like C, Pascal, and Fortran) introduced functions (or procedures). The program was broken down into a series of functional calls.
Focus on Actions: The primary concern was what the program is doing (the algorithms) rather than the data it is operating on.
Top-Down Design: A main function controls the flow, calling smaller sub-functions, breaking the problem down.
Global Data Vulnerability: Functions needed to share data, so data was often declared globally. Any function could accidentally modify the global data, leading to catastrophic side effects.
⇒The Crisis of POP
As enterprise applications grew into hundreds of thousands of lines of code, POP failed. The separation of data and functions meant that if the data structure changed, every single function that touched that data had to be manually rewritten. It was fragile, non-scalable, and did not reflect how humans perceive the real world.
Page 2
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
2. The Object-Oriented Paradigm
Object-Oriented Programming (OOP) fundamentally shifts the perspective: instead of asking 'What actions need to happen?', OOP asks 'What entities are involved?'.
⇒Core Philosophy of OOP
OOP models the software exactly like the real world. In the real world, entities (objects) have attributes (state) and behaviors (functions). In OOP, data and the functions that operate on that data are bound together into a single, secure unit.
Bottom-Up Approach: You design the small foundational entities (classes) first, and then build the larger system by having these entities interact.
Data Security: Data is hidden from the outside world. It can only be accessed through the specific functions provided by the entity.
Real-World Mapping: A 'Bank Account' is an object. It has data (balance) and functions (deposit, withdraw).
Procedural vs Object-Oriented Programming
Feature
POP (e.g., C)
OOP (e.g., C++)
Primary Focus
Functions / Logic
Data / Objects
Design Approach
Top-Down
Bottom-Up
Data Access
Data moves freely; often global
Data is hidden and protected
Modifiability
Hard to add new data/functions
Highly extensible
Real-world fit
Poor mapping to real-world
Excellent mapping to real-world
Page 3
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
3. Pillar 1: Encapsulation
The entire foundation of OOP rests on four conceptual pillars. The most fundamental of these is Encapsulation.
⇒What is Encapsulation?
Encapsulation is the physical wrapping of data (variables) and functions (methods) into a single cohesive unit, known as a Class. By grouping them together, the language ensures that the data is inextricably linked to the code that manipulates it.
⇒Data Hiding (Information Hiding)
Encapsulation naturally leads to Data Hiding. By wrapping data inside a class, we can place a barrier around it, preventing direct external access. This prevents unauthorized interference and accidental corruption.
External Code (Main Function)
↓ Restricted Access ↓
[ Public Methods (Getters/Setters) ]
↓ Unrestricted Access ↓
[ Private Data (Hidden inside Class) ]
The Encapsulation Barrier
Think of a television. You do not interact directly with the internal wiring and capacitors (the private data). You interact with the remote control and buttons (the public methods). If you want to change the channel, you press a button, and the television handles the internal logic safely.
Page 4
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
4. Pillar 2: Abstraction
While Encapsulation is about hiding internal state for security, Abstraction is about hiding internal complexity to reduce cognitive load.
⇒What is Abstraction?
Data Abstraction refers to providing only essential information to the outside world and hiding their background details. It focuses on WHAT an object does, rather than HOW it does it.
The User's View
When you use the `sqrt()` function in C++, you only need to know that it takes a number and returns its square root. This is abstraction.
The Engineer's View
You do not need to know the complex mathematical algorithm running inside `sqrt()`. The complexity is abstracted away.
⇒Implementation in C++
Abstraction in C++ is achieved through two main mechanisms:
Classes: A class exposes a public interface (methods) while keeping its core algorithms and data private.
Header Files: You include `<iostream>` and use `cout`. You are utilizing abstraction because you don't care how `cout` writes bits to the hardware display.
Page 5
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
5. Inheritance & Polymorphism
⇒Pillar 3: Inheritance
Inheritance is the mechanism by which one class acquires the properties and behaviors of another class. It models the 'IS-A' relationship in the real world.
Reusability: Instead of rewriting code, a new class can absorb existing, debugged code from a parent class.
Hierarchical Classification: You can define a general `Vehicle` class, and inherit it to create specific `Car` and `Truck` classes.
If a `Vehicle` class already has code for `startEngine()`, the `Car` class inherits this function for free without writing a single line of logic for it.
⇒Pillar 4: Polymorphism
Polymorphism means 'the ability to take many forms'. It allows a single interface or function name to be used for a general class of actions. The specific action is determined by the exact nature of the situation.
Operator Overloading
The + operator adds integers, but can be redefined to concatenate strings.
Function Overloading
Having multiple functions named 'draw()', but one takes a circle, the other takes a square.
Polymorphism is what allows C++ to be highly extensible. You can write generic code that handles a base class, and it will automatically execute the correct derived behavior at runtime.
Page 6
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
6. Classes and Objects in Depth
A Class is the fundamental building block of OOP in C++. It is an expansion of the C `struct`.
⇒What is a Class?
A Class is a user-defined data type. It is a logical blueprint or template that defines the characteristics (data) and behaviors (functions) that the objects created from it will possess.
A class itself does not consume any memory for data when it is defined.
It strictly acts as a logical specification.
⇒What is an Object?
An Object is a physical, run-time entity that is instantiated (created) from a class. When an object is created, the system allocates physical memory to hold its specific state.
Defining a Class and Instantiating an Object
class Employee {
// The Blueprint
int employeeId;
float salary;
public:
void setDetails(int id, float s);
void display();
}; // Semicolon is mandatory!
int main() {
// Instantiation
Employee emp1; // Memory allocated here
Employee emp2; // Separate memory allocated here
}
When `emp1` and `emp2` are created, they get their own independent copies of `employeeId` and `salary` in the system's RAM.
Page 7
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
7. Access Specifiers
Access specifiers define the boundary of encapsulation. They dictate exactly who is allowed to read or modify the members of a class.
⇒The Three Boundaries
1. Private
Members declared as private can ONLY be accessed by the member functions of that exact same class. This is the ultimate security layer. If you omit an access specifier, C++ defaults to private.
2. Public
Members declared as public can be accessed from anywhere in the entire program where the object is visible, including the `main()` function.
3. Protected
Crucial for inheritance. Protected members are hidden from the outside world (like private), but they CAN be accessed by child/derived classes.
Demonstrating Access
class BankAccount {
private:
double balance; // Hidden
public:
void deposit(double amount) {
if(amount > 0) balance += amount; // Class can access private data
}
};
int main() {
BankAccount acc;
// acc.balance = 1000; // COMPILER ERROR! Cannot access private.
acc.deposit(1000); // VALID. Accessing via public method.
}
Page 8
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
8. Defining Member Functions
Member functions (methods) contain the logic that manipulates class data. C++ provides two physical locations where these functions can be defined.
⇒1. Inside the Class Definition
When a function is completely defined inside the class body, the C++ compiler implicitly treats it as an `inline` function.
class Circle {
double radius;
public:
// Defined inside
double getArea() {
return 3.14159 * radius * radius;
}
};
This is excellent for very small functions (like getters/setters) because inline functions eliminate function call overhead. However, writing large functions inside the class clutters the blueprint.
⇒2. Outside the Class Definition
For clean code, we declare the function prototype inside the class, and write the actual definition outside using the Scope Resolution Operator (`::`).
class Circle {
double radius;
public:
double getArea(); // Declaration only
};
// Defined outside
double Circle::getArea() {
return 3.14159 * radius * radius;
}
Page 9
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
9. Memory Allocation & Layout
Understanding how C++ allocates memory for objects is critical for optimizing high-performance applications.
⇒The Memory Split
When you create an object, you might assume memory is allocated for both its variables and its functions. This is a misconception. To save memory, C++ splits the physical layout.
Data Members (Variables): Every single object gets its own separate block of memory for data variables. If you create 100 `Employee` objects, there are 100 copies of `employeeId` in RAM.
Member Functions (Code): Functions are compiled into machine instructions. They do not change from object to object. Therefore, only ONE copy of the member functions is kept in memory. All 100 objects share this same code block.
Shared Memory Region: [ function code for getDetails(), display() ]
But if all objects share the same function code, how does the function know WHICH object's data to operate on? C++ solves this silently by passing a hidden pointer, known as the `this` pointer, to the function under the hood.
Page 10
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
10. Static Data Members
We just established that every object gets its own copy of data variables. But what if we want a piece of data to be shared across ALL objects of a class? We use the `static` keyword.
⇒Properties of Static Variables
Initialization: It is automatically initialized to zero when the first object is created (unless given a specific value).
Single Copy: Only ONE copy of the static member is created, regardless of how many objects exist. It is shared by all.
Scope: Its scope is within the class, but its lifetime is the entire program execution.
⇒The Definition Rule
A static variable is declared inside the class, but it MUST be defined outside the class. This is because static variables are stored separately from objects, so the compiler needs an explicit definition to allocate that memory.
Tracking total objects created
class Item {
static int count; // Declaration
int id;
public:
Item() { count++; } // Increment shared variable
};
// Definition outside the class (Mandatory)
int Item::count = 0;
If you create 50 `Item` objects, they all share the exact same `count` variable, which will hold the value 50.
Page 11
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
11. Static Member Functions
Just as data can be static, member functions can also be declared static. A static member function is fundamentally tied to the Class itself, not to any specific object instance.
⇒Strict Rules for Static Functions
A static function can ONLY access other static members (data or functions) of the same class.
It CANNOT access normal, non-static data members. (Because it doesn't belong to an object, it has no `this` pointer, so it doesn't know whose non-static data to access).
It can be invoked directly using the class name, without creating any objects.
Using Static Functions
class Server {
static int activeConnections;
int serverId;
public:
static void showConnections() {
// cout << serverId; // ERROR! Cannot access non-static
cout << "Connections: " << activeConnections; // OK
}
};
int Server::activeConnections = 5;
int main() {
// Called without creating any Server object!
Server::showConnections();
}
Page 12
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
12. Arrays of Objects
In C++, an array is a collection of variables of the same type. Since a class is just a user-defined type, we can easily create an array of objects.
⇒Memory Representation
When an array of objects is declared, the compiler allocates a contiguous block of memory to store all the objects sequentially.
Creating an Array of Objects
class Student {
int rollNo;
float marks;
public:
void getInfo();
void display();
};
int main() {
// Allocates memory for 60 Student objects contiguously
Student sectionA[60];
// Accessing individual objects via index
for(int i=0; i<60; i++) {
sectionA[i].getInfo();
}
}
Arrays of objects are extensively used in enterprise systems to manage large datasets in memory, such as a roster of employees, a ledger of transactions, or a swarm of enemies in a video game.
Page 13
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
13. Objects as Arguments
Objects can be passed to functions just like standard data types. However, because objects can be massive (containing megabytes of data), the method of passing is critical for performance.
⇒1. Pass by Value
A complete bit-by-bit copy of the object is created and passed to the function. Modifications made inside the function DO NOT affect the original object.
Pros: Safe. Original data cannot be corrupted.
Cons: Extremely slow. Copying large objects exhausts memory and CPU cycles.
⇒2. Pass by Reference
Instead of copying, the actual memory address is passed implicitly using the `&` operator.
Fast and Efficient Passing
void updateBalance(BankAccount &acc) {
// Modifies the ORIGINAL object directly
acc.deposit(500);
}
⇒3. Pass by Const Reference
The industry standard. It combines the speed of pointers with the safety of pass-by-value. The object is passed without copying, but the `const` keyword prevents the function from modifying it.
void displayData(const LargeMatrix &matrix) {
// Fast, but read-only!
}
Page 14
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
14. Friend Functions
Encapsulation says that private data cannot be accessed from outside the class. However, C++ provides a controlled loophole: the `friend` function.
⇒What is a Friend Function?
A friend function is a non-member function that is explicitly granted the right to access the `private` and `protected` members of a class. The class itself must grant this permission.
Not in Scope: It is not a member function, so it is not called using an object (`obj.friendFunc()` is illegal).
Argument Requirement: Because it lacks a `this` pointer, you must explicitly pass the object(s) to it as arguments.
Declaration: It can be declared anywhere in the class (public or private), preceded by the keyword `friend`.
Bridging Two Classes
class Beta; // Forward declaration
class Alpha {
int data;
friend void findMax(Alpha a, Beta b);
};
class Beta {
int data;
friend void findMax(Alpha a, Beta b);
};
void findMax(Alpha a, Beta b) {
// Accessing private data of TWO distinct classes!
if(a.data > b.data) cout << a.data;
else cout << b.data;
}
Friend functions are heavily utilized in Operator Overloading, especially when the left operand is a standard type (like an integer) rather than a class object.
Page 15
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
15. Friend Classes & Returns
⇒Friend Classes
Just as a specific function can be a friend, an entire class can be declared a friend of another class. This means every single member function in the friend class has full access to the private data of the other class.
class SecureVault {
int passcode;
friend class Administrator;
};
class Administrator {
public:
void resetCode(SecureVault &v) {
v.passcode = 0000; // Unrestricted access
}
};
⇒Returning Objects from Functions
Functions can also return an entire object. This is typically done when a function performs an operation on two objects and produces a third object as a result.
Returning an Object
Complex add(Complex c1, Complex c2) {
Complex temp;
temp.real = c1.real + c2.real;
temp.imag = c1.imag + c2.imag;
return temp; // Returns a copy of the temp object
}
Page 16
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 1 —
16. Unit 1 Revision Checklist
⇒End-of-Unit Verification
Before moving to Constructors and Destructors, ensure you can fluently answer the following questions without referring to these notes:
Paradigm Shift: Compare POP and OOP focusing on data security and extensibility.
The 4 Pillars: Define Encapsulation, Abstraction, Inheritance, and Polymorphism using real-world analogies.
Memory Map: Explain exactly how memory is allocated for 10 objects of a class. Distinguish between data member allocation and member function allocation.
Access Control: Describe a scenario where you would use `protected` instead of `private`.
Scope: Write the syntax for defining a member function outside the class using the scope resolution operator.
Static: Write a program demonstrating a static data member tracking object counts.
Static Rules: Explain why a static member function cannot use the `this` pointer.
References: Justify why passing objects by reference is preferred over passing by value in large systems.
Friends: Write a program bridging two separate classes using a shared friend function.