Unit -3
Object-Oriented Programming: Classes & Objects
Course Overview
Core Concepts:
• Classes, objects, objects memory management
• Constructor and Destructor
• Objects as function argument
• Returning objects from function
• Static members
• Member functions defined outside the class
What is a Class?
A class is a blueprint or template that defines the characteristics and behaviors of objects. It encapsulates data (attributes)
and functions (methods) that operate on that data into a single unit.
Structure Purpose
• Contains data members (attributes) • Creates a user-defined data type
• Contains member functions (methods) • Serves as a template for creating objects
• Defines access permissions (public, private, protected) • Implements abstraction and encapsulation
In C++, a class is defined using the class keyword followed by the class name and a block of code that contains member declaratio
class ClassName {
// Data members (attributes)
// Member functions (methods)
};
What is an Object?
An object is an instance of a class that encapsulates data and behavior into a single unit. It is a real-world
entity created from the class blueprint.
Key Characteristics:
• Contains specific values for the attributes defined in the class
• Can perform operations through its member functions
• Occupies memory space when instantiated
• Has its own unique identity
For example, if Car is a class defining attributes like color, model, and year, then myCar (with color red,
model Sedan, year 2023) would be a specific object of the Car class.
Class vs Object Relationship
Class Object
• Template or blueprint • Instance of class
• Logical entity • Physical entity
• Defined once • Can create multiple
• No memory allocated on definition • Memory allocated on creation
Simple Class Syntax
class ClassName {
private:
// private data members
public:
// public member functions
// constructors, destructor
};
Creating a Simple Class
Define Class NameChoose a descriptive name using PascalCase
Declare Data MembersAttributes that store object state
Implement Member FunctionsMethods that define object behavior
Set Access SpecifiersControl visibility with public, private, protected
Example: Student Class
class Student {
private:
int rollNo;
std::string name;
float marks;
public:
void setData(int r, std::string n, float m);
void displayData();
};
Creating Objects
There are several ways to instantiate objects in C++:
Stack Allocation
ClassName objectName;
Heap Allocation
ClassName* objectName = new ClassName();
Array of Objects
ClassName objectNames[size];
Accessing Class Members
Dot Operator
objectName.memberName
Arrow Operator
pointerToObject->memberName
Scope Resolution
ClassName::staticMember
Access Specifiers
Protected
• Accessible in class and subclasses
• Supports inheritance
Private
• Limited visibility
• Accessible only within class
• Default access level
• Enforces encapsulation Public
• Accessible from anywhere
• Exposed functionality
Public Access Specifier
Members declared as public are accessible from any part of the program, including from outside the class.
class Circle {
public:
double radius;
double getArea() {
return 3.14159 * radius * radius;
}
void setRadius(double r) {
radius = r;
}
};
In this example, both the radius data member and the getArea() and setRadius() functions are accessible outside the class:
int main() {
Circle myCircle;
// Direct access to public data member
myCircle.radius = 5.0;
// Calling public member functions
myCircle.setRadius(7.5);
double area = myCircle.getArea();
}
Private Access Specifier
Members declared as private are only accessible within the class itself, not from outside the class or derived classes.
class BankAccount {
private:
double balance; // Private data member
int accountNumber; // Private data member
public:
// Public interfaces to access private data
void deposit(double amount) {
balance += amount;
}
double getBalance() {
return balance;
}
void setAccountNumber(int num) {
accountNumber = num;
}
};
int main() {
BankAccount account;
// Error: Cannot access private members
// account.balance = 1000.0; // Compilation error
// account.accountNumber = 12345; // Compilation error
// Correct: Access through public methods
account.deposit(1000.0);
account.setAccountNumber(12345);
double currentBalance = account.getBalance();
}
Private members help implement encapsulation.
Protected Access Specifier
Members declared as protected are accessible within the class itself and by all classes that inherit from it, but not from outside these classes.
class Shape {
protected:
double width; // Protected data member
double height; // Protected data member
public:
void setDimensions(double w, double h) {
width = w;
height = h;
}
};
class Rectangle : public Shape {
public:
// Can access protected members from base class
double getArea() {
return width * height; // Access to protected members
}
};
int main() {
Rectangle rect;
rect.setDimensions(5.0, 3.0);
// Error: Cannot access protected members
// rect.width = 10.0; // Compilation error
// Correct: Access through public methods
double area = rect.getArea();
}
What are Constructors?
Special Member Functions
Initialize newly created objects
Same Name as Class
Called automatically on object creation
No Return Type
Not even void
Default Constructor
No Parameters Compiler-Generated
Takes no arguments Created automatically if no constructor defined
Default Initialization Usage
Primitive types remain uninitialized Student s1;
Default Constructor Example
class Rectangle {
private:
int length;
int width;
public:
// Default constructor
Rectangle() {
length = 0;
width = 0;
}
};
// Usage
Rectangle rect; // Calls default constructor
Parameterized Constructor
Accepts Parameters: Takes arguments to initialize object data members with custom values
Student(int rollNo, string name)
Multiple Signatures: Can overload with different parameter sets enabling flexible object initialization
Explicit Initialization: Called directly using syntax:
ClassName obj(arg1, arg2); or ClassName obj = ClassName(arg1, arg2);
Constructor Overloading: Allows multiple ways to initialize the same class
No Default Constructor: When parameterized constructors exist, compiler doesn't create default
constructor automatically
Parameterized Constructor Example
class Rectangle {
private:
int length;
int width;
public:
// Parameterized constructor
Rectangle(int l, int w) {
length = l;
width = w;
}
};
// Usage
Rectangle rect1(10, 5); // l=10, w=5
Copy Constructor
Creates Object Copies
Initializes using existing object
Reference Parameter
Takes const reference to class type
Implicit Invocation
Called for pass-by-value, return objects
Copy Constructor Example
class Rectangle {
private:
int length;
int width;
public:
// Constructor
Rectangle(int l, int w) {
length = l;
width = w;
}
// Copy constructor
Rectangle(const Rectangle &rect) {
length = rect.length;
width = rect.width;
}
};
// Usage
Rectangle rect1(10, 5);
Rectangle rect2 = rect1; // Copy constructor called
Default Copy Constructor
When you don't define a copy constructor, C++ provides one automatically with the signature:
ClassName(const ClassName &source);
Compiler-Generated Member-Wise Copy Shallow Copy
Automatically created when no Copies each data member value Only copies pointer addresses,
explicit copy constructor is directly using their respective not the data they point to. This
defined in your class. This copy operations. For primitive creates two objects with pointers
implicit constructor performs a types, this means a direct value to the same memory, leading to
field-by-field copy of all class copy; for class types, their copy double-free errors when
members. constructors are called. destructors are called or when
one object modifies shared data.
Unlike user-defined copy constructors, the default copy constructor cannot perform deep copying of dynamically allocated m
Destructor
Cleanup Operations Tilde Syntax
Frees resources when object dies ~ClassName()
No Parameters Automatic Call
Cannot be overloaded When object goes out of scope
Destructor Example
class DynamicArray {
private:
int* arr;
int size;
public:
// Constructor
DynamicArray(int s) {
size = s;
arr = new int[size];
}
// Destructor
~DynamicArray() {
delete[] arr; // Free allocated memory
}
};
Objects as Function Arguments
Pass by Value Pass by Reference
• Creates copy of object • Uses original object
• Invokes copy constructor • No copying occurs
• Changes don't affect original • Changes affect original
• Less efficient for large objects • More efficient
Pass by Value Example
// Pass by value
void displayRectangle(Rectangle rect) {
// Works with a copy of the rectangle
cout << "Length: " << rect.getLength() << endl;
cout << "Width: " << rect.getWidth() << endl;
// Modification stays local
rect.setLength(100); // Original unchanged
}
Rectangle myRect(5, 10);
displayRectangle(myRect); // Copy constructor called
Pass by Reference Example
// Pass by reference
void modifyRectangle(Rectangle &rect) {
// Works with the original rectangle
// No copy constructor called
// Modification affects original
rect.setLength(100); // Original changed
}
Rectangle myRect(5, 10);
modifyRectangle(myRect); // No copying
Returning Objects from Functions
• Return by Value
• Creates temporary copy of object
• Return by Reference
• Returns reference to existing object
• Return by Pointer
• Returns address of dynamic object
Return by Value Example
Creates a copy of the object.
Safe but can be slower (unless optimized with move semantics or RVO).
Object is temporary and managed by the caller.
// Return by value
Rectangle createRectangle(int l, int w) {
Rectangle temp(l, w);
return temp; // Copy constructor called
}
// Usage
Rectangle myRect = createRectangle(5, 10);
Return by Reference Example
Returns a reference to an existing object.
• Avoids copying.
⚠️Must not return reference to a local (stack) variable — causes undefined behavior.
Point& getReference(Point &p) {
return p; // Safe: returns reference to caller's object
}
int main() {
Point p2(5, 7);
Point &p3 = getReference(p2);
p3.x = 100;
cout << "p2: " << p2.x << ", " << p2.y << endl; // p2.x is now 100
}
Return by pointer
Returns a pointer to an object.
Often used with dynamically allocated memory (new).
Caller is responsible for delete (manual memory management).
Point* createDynamicPoint() {
Point* p = new Point(1, 2);
return p;
}
int main() {
Point* p4 = createDynamicPoint();
cout << "p4: " << p4->x << ", " << p4->y << endl;
delete p4; // Clean up memory
}
Structures vs Classes
Structures Classes
• Default access: public • Default access: private
• Traditional data grouping • OOP paradigm
• Compatible with C • C++ specific
• Typically for passive data • Data + behavior encapsulation
Structure vs Class Syntax
Structure Class
struct Student { class Student {
// Public by default // Private by default
int id; int id;
string name; string name;
void display() { public:
cout << id << name; void display() {
} cout << id << name;
}; }
};
Memory Allocation for Objects
Stack Heap Static
Local Objects Dynamic Objects Static Objects
Automatic allocation/deallocation Manual memory management Lifetime throughout program
with new/delete execution
Stack Memory Example
Automatic memory management
Memory is freed automatically when the function/block ends
• Fast access
Lives temporarily
void someFunction() {
// Stack allocation
Rectangle rect(10, 20);
// rect is automatically destroyed
// when function ends
} // Destructor called here
Heap Memory Example
Dynamic allocation using new
Memory must be manually freed using delete
• Useful when size/lifetime is not known at compile time
Lives until explicitly deleted
void someFunction() {
// Heap allocation
Rectangle* rectPtr = new Rectangle(10, 20);
// Must manually free memory
delete rectPtr; // Destructor called here
// Forgetting delete causes memory leak
}
Static Allocation Example
Allocated once and persists for entire program lifetime
Exists even after function exits
• Useful for constants, global/shared state
void createPoint() {
static Point p(10, 20); // allocated in static memory
cout << p.x << ", " << p.y << endl;
}
🔁 Summary Table:
Type Lifetime Allocated Where Manual Deletion Example Syntax
Stack Function/block Stack ❌ No Point p;
scope
Heap Until delete Heap ✅ Yes new Point() / delete
Static Whole program Static/Global ❌ No static Point p;
Memory Layout of Objects
Objects store data members in memory sequentially. Functions share one copy across all instances. Virtual
functions use vtable.
🧠 What is "Memory Layout" of an Object?
It refers to how an object’s data is organized in memory — the order, alignment, and size of its data members, i
• Member variables
Padding for alignment
• Virtual table pointer (if applicable)
Static Data Members
class Student {
private:
int id;
static int totalStudents; // Declaration
public:
Student() {
id = ++totalStudents;
}
static int getCount() {
return totalStudents;
}
};
// Definition required outside class
int Student::totalStudents = 0;
// Usage
cout << Student::getCount(); // 0
Student s1, s2;
cout << Student::getCount(); // 2
Static Member Functions
Class-level Functions Limited Access No 'this' Pointer
Not tied to specific object instance Can only access static members Cannot access instance members
Static Member Functions Example
Static member functions belong to the class rather than any specific object instance:
class Calculator {
private:
static int operationCount;
public:
// Static member function
static int add(int a, int b) {
operationCount++;
return a + b;
}
// Static member function to access static data
static int getOperationCount() {
return operationCount;
}
// Non-static functions can access both static and non-static members
void displayCount() {
cout << "Operations performed: " << operationCount << endl;
}
};
// Definition required outside class
int Calculator::operationCount = 0;
// Usage - no object needed for static methods
cout << Calculator::add(5, 3) << endl; // Outputs: 8
cout << Calculator::getOperationCount() << endl; // Outputs: 1
Static member functions can be called using the class name without creating any objects, making them useful for utility functions and managing class-wide data.
Member Functions Outside Class
Functions can be defined outside the class for better organization:
Declaration Inside: Function prototype within class definition
Definition Outside: Implementation with scope resolution operator
Better Organization: Separates interface from implementation
External Member Function Example
// Class declaration
class Rectangle {
private:
int length;
int width;
public:
Rectangle(int l, int w);
int area();
int perimeter();
};
// External implementations
Rectangle::Rectangle(int l, int w) {
length = l;
width = w;
}
int Rectangle::area() {
return length * width;
}
int Rectangle::perimeter() {
return 2 * (length + width);
}