📘 Lecture 26: Classes, Objects, and Constructors
🔹 1) Classes and Objects
Class:
A class is a user-defined data type that acts as a blueprint for creating objects. It can have data
members (variables) and member functions (functions inside the class).
Object:
An object is a real-world instance of a class. It holds actual values and can access class
functions.
🔹 2) Definition of a Class
Syntax:
class ClassName {
// data members
// member functions
};
Example:
class Student {
public:
string name;
int age;
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
🔹 3) Separation of Interface from Implementation
Definition:
This means writing the function declarations inside the class and writing their definitions
outside the class using the :: (scope resolution) operator.
Purpose:
Improves code organization and makes large projects easier to manage.
Example:
class Student {
public:
void show(); // only declared here
};
void Student::show() {
cout << "Showing student info.\n";
}
🔹 4) Structure of a Class
A typical class has:
1. Access specifiers: public, private
2. Data members
3. Member functions
4. Constructors/Destructors
Structure Example:
class Car {
private:
int speed;
public:
Car(); // constructor
void drive(); // function
};
🔹 5) Sample Program
#include <iostream>
using namespace std;
class Student {
public:
string name;
int age;
void input() {
cout << "Enter name and age: ";
cin >> name >> age;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Student s;
s.input();
s.display();
return 0;
}
🔹 6) Constructor
Definition:
A constructor is a special function that runs automatically when an object is created. It has the
same name as the class and no return type.
Purpose:
To initialize objects with default or specific values.
Example:
class Student {
public:
string name;
int age;
Student() {
name = "Ali";
age = 18;
}
};
🔹 7) Default Arguments with Constructors
Definition:
You can provide default values to constructor parameters.
Purpose:
To allow object creation with or without passing all values.
Example:
class Student {
public:
string name;
int age;
Student(string n = "Unknown", int a = 0) {
name = n;
age = a;
}
void show() {
cout << name << " " << age << endl;
}
};
int main() {
Student s1;
Student s2("Ali", 21);
s1.show(); // Unknown 0
s2.show(); // Ali 21
}
✅ Summary
• A class defines the structure of objects.
• Objects are instances of classes.
• Use constructors to initialize objects automatically.
• Separate interface and implementation to keep code clean.
• Default arguments make constructors flexible.
📘 Lecture 27: Classes, Constructors, Utility Functions &
Destructors
🔹 1) Classes and Objects (Recap)
• Class: A blueprint that defines attributes (variables) and behaviors (functions).
• Object: An instance of a class created using the class structure.
class Car {
public:
string brand;
void drive() {
cout << "Driving " << brand << endl;
}
};
Car myCar; // Object
🔹 2) Constructors
• A constructor is a special function that is automatically called when an object is created.
• It has the same name as the class and no return type.
• Used to initialize objects.
class Student {
public:
string name;
Student() {
name = "No Name";
}
};
🔹 3) Types of Constructors
1. Default Constructor
o Takes no parameters.
o Called when object is created without any arguments.
Student() { name = "Default"; }
2. Parameterized Constructor
o Takes arguments to initialize object with specific values.
Student(string n) { name = n; }
3. Copy Constructor
o Used to copy data from one object to another.
Student(const Student &s) {
name = s.name;
}
🔹 4) Utility Functions
Definition:
Functions that support internal working of the class. They are usually declared private or
protected and are not meant to be directly called by users.
Example:
class Math {
private:
int square(int n) {
return n * n;
}
};
Common Examples of Utility Functions:
• Helper methods for calculations.
• Validation checks.
• Formatting functions, etc.
🔹 5) Destructors
Definition:
A destructor is a special function that is called automatically when an object is destroyed.
• Same name as the class but preceded by a tilde (~).
• No parameters, no return type.
• Used to free resources like memory or files.
class Student {
public:
~Student() {
cout << "Destructor called!" << endl;
}
};
When object s1 goes out of scope, the destructor is automatically called.
✅ Summary
• Classes are user-defined types; objects are their instances.
• Constructors help initialize objects.
• There are three types of constructors: default, parameterized, and copy.
• Utility functions help in internal operations of the class.
• Destructors handle cleanup when objects are destroyed.
📘 Lecture 28: Memory Allocation, Classes, and Abstraction
in C++
🔹 1) Lecture Overview
This lecture introduces how memory is allocated in C vs C++, the use of new and delete for
dynamic memory, and how C++ classes improve upon structures. It also covers abstraction,
messages, and extending language through classes.
🔹 2) Memory Allocation in C
• Uses malloc(), calloc(), and free() for dynamic memory.
• No constructors/destructors, so we manually initialize and deallocate.
int* ptr = (int*)malloc(sizeof(int));
*ptr = 5;
// Later
free(ptr);
🔹 3) Memory Allocation in C++
• Uses new for allocation and delete for deallocation.
• Automatically calls constructors and destructors.
int* ptr = new int;
*ptr = 10;
delete ptr;
🔹 4) new Operator and Classes
• new not only allocates memory but also calls the class constructor.
class Student {
public:
Student() {
cout << "Constructor called\n";
}
};
Student* s = new Student(); // dynamically creates and initializes object
🔹 5) Classes and Structures in C++
• C++ Structures can have functions, unlike C structures.
• Default access:
o class members are private by default.
o struct members are public by default.
struct Data {
int x;
void show() {
cout << x;
}
};
🔹 6) new Operator and Constructors
• When using new, constructor is automatically called.
• We can also call parameterized constructors.
class Test {
public:
Test(int a) {
cout << "Value: " << a;
}
};
Test* t = new Test(5);
🔹 7) delete Operator and Classes
• delete destroys dynamically created object and calls the destructor.
delete s; // If `s` is a pointer to object created with `new`
🔹 8) new, delete Outside Constructors and Destructors
• You can use new and delete inside any function, not just constructors or destructors.
• Common in factory methods or resource management.
void create() {
Student* s = new Student();
delete s;
}
🔹 9) main() Function and Classes
• main()can use new/delete for objects.
• Demonstrates object creation lifecycle in a full program.
🔹 10) Class Abstraction
• Abstraction means hiding internal implementation details and showing only necessary
functionalities.
• Done using:
o Private data
o Public methods
o Interfaces
class Account {
private:
double balance;
public:
void deposit(double amt);
void showBalance();
};
🔹 11) Messages and Methods
• Message = function call (like obj.method()).
• Objects communicate via messages.
• Methods define behavior in response to messages.
car.start(); // message sent to car object to execute start()
🔹 12) Classes to Extend the Language
• C++ classes allow us to create new data types and extend the programming language.
• You define your own types with functions and operators.
class Complex {
// define new number type with +, -, *, /
};
✅ Summary
Topic Key Point
Memory in C Uses malloc, free, no constructors
Topic Key Point
Memory in C++ Uses new, delete, with constructors/destructors
new and delete Used for dynamic allocation and cleanup
Class vs Struct Structs can have methods; default access differs
Abstraction Hide details, expose interface
Messages & Methods Objects communicate via function calls
Extend Language Classes let you define new, powerful data types
📘 Lecture 29: Friend Functions and Friend Classes in C++
🔹 6) Friend Functions
• A friend function is a non-member function that has access to the private and
protected members of a class.
• It is not part of the class, but is granted special access.
• Useful when two or more classes need to interact closely.
✅ Key Points:
• Declared inside class using friend keyword.
• Defined like a normal function (outside the class).
• Can access private data members.
📌 Example:
class Box {
private:
int length;
public:
Box() : length(0) {}
friend void printLength(Box); // Friend function declaration
};
void printLength(Box b) {
cout << "Length is: " << b.length << endl; // Accessing private member
}
🔹 7) Declaration of Friend Functions
• Declared inside class with the friend keyword.
• Defined outside the class like a normal function.
• Can also be friend to multiple classes.
📌 Syntax:
class A {
friend void show(A); // Declaration
};
🧠 Notes:
• Friend function can’t be called with object.function().
• It is not a class member, so it doesn't use this pointer.
• Usually used when external function needs internal access.
🔹 11) Friend Classes
• A friend class can access private and protected members of another class.
• This is useful for tightly coupled classes where one class needs full access to another.
📌 Syntax:
class B; // Forward declaration
class A {
private:
int x;
public:
A() { x = 10; }
friend class B; // B is friend of A
};
class B {
public:
void showA(A a) {
cout << "A's private x: " << a.x << endl;
}
};
✅ Use Cases:
• When one class manages or operates on another.
• Operator overloading between different classes.
• Utility or helper classes.
✅ Summary Table
Concept Description
Friend A function that is not a member of the class but can access private/protected
Function members.
Declaration Declared inside the class using friend, defined outside like a normal function.
Friend Class A class that can access all private/protected members of another class.
📘 Lecture 30: Reference Data Type in C++
🔹 13) Reference Data Type
• A reference is an alias (another name) for an existing variable.
• It must be initialized at the time of declaration.
• Once a reference is set to a variable, it cannot be changed to refer to another variable.
• Syntax uses ampersand & after the data type.
📌 Syntax:
int a = 10;
int &ref = a; // ref is a reference to a
✅ Key Points:
• Changes made to ref also affect a.
• Mainly used for:
o Function parameters (pass by reference)
o Returning values from functions efficiently
🔁 Example:
#include <iostream>
using namespace std;
void updateValue(int &x) {
x += 5;
}
int main() {
int num = 10;
updateValue(num); // Passed by reference
cout << num; // Output: 15
return 0;
}
🔹 15) Difference Between References and Pointers
Feature References Pointers
Syntax int &ref = var; int *ptr = &var;
Null Assignment Cannot be null Can be null
Reassignment Cannot refer to another variable Can point to another variable
Memory Address Acts like alias, no extra memory used Uses separate memory
Dereferencing Not needed Requires * to dereference
Use with Arrays Less flexible More flexible
🔹 16) Dangling References
• A dangling reference occurs when a reference points to an object that no longer
exists.
• Typically caused when referencing a local variable that goes out of scope.
⚠️ Example:
int& getRef() {
int x = 10;
return x; // ❌ Dangerous: x will be destroyed after function ends
}
💡 Tip:
• Never return references to local variables.
• Prefer returning by reference only when returning static or global variables, or
dynamically allocated memory.
✅ Summary
Topic Description
Reference Data Type Alias to another variable, must be initialized, can't change reference target.
References vs Pointers References are simpler, safer; pointers are more flexible.
Dangling Reference Occurs when reference refers to memory that has been deallocated.
📘 Lecture 31: Operator Overloading in C++
🔹 What is Operator Overloading and Why is it Required?
• Operator Overloading allows us to redefine the meaning of an operator (like +, -, *,
etc.) for user-defined data types (classes).
• It helps make object-oriented code more intuitive and readable, similar to how
operators work with built-in types.
📌 Example:
Complex c1, c2, c3;
c3 = c1 + c2; // '+' operator is overloaded for Complex type
🔹 Where is it Relevant to Apply?
• When working with classes like Complex, Matrix, Vector, Fraction, etc.
• Useful in mathematical, logical, or I/O-based operations involving custom types.
• Makes code cleaner and closer to natural language.
🔹 Operators You Can Overload
Most operators can be overloaded, such as:
Arithmetic Relational Logical Assignment Others
+, - ==, != && = [], ()
*, / <, > ` `
🔹 Restrictions on Operator Overloading
❌ Operators that cannot be overloaded:
• :: (Scope Resolution)
• . (Member Access)
• .* (Pointer to member)
• sizeof
• typeid
• ?: (Ternary Operator)
📌 Other Rules:
• You cannot create new operators, only redefine existing ones.
• Operator overloading must preserve original operator syntax and arity (unary,
binary).
🔹 Examples of Operator Overloading
✅ Member Function Overloading:
class Complex {
public:
int real, imag;
Complex operator+(const Complex &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
};
✅ Non-Member (Friend) Function:
class Complex {
int real, imag;
public:
Complex(int r = 0, int i = 0): real(r), imag(i) {}
friend Complex operator+(Complex c1, Complex c2);
};
Complex operator+(Complex c1, Complex c2) {
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
🔹 Non-Member Operator Functions
• Used when:
o The left-hand operand is not an object of the class.
o Overloading I/O operators (<<, >>) which must be non-member functions.
Example: Overloading << operator
ostream& operator<<(ostream &out, const Complex &c) {
out << c.real << " + " << c.imag << "i";
return out;
}
✅ Summary Table
Topic Description
Operator Overloading Redefining built-in operators for user-defined types
Where to Apply For making custom class operations more intuitive
Overloadable Operators Most operators except a few like ::, ., sizeof
Restrictions Syntax/arity must match original behavior
Non-Member Functions Used when first operand isn't a class object or for I/O
📘 Lecture 32: Operator Overloading (Continued)
🔹 19) Overloading Minus Operator (-)
Operator overloading allows you to define custom behavior for the minus operator when used
with objects of a class.
✅ Example: Overload - for a Point class
class Point {
public:
int x, y;
Point(int a = 0, int b = 0) : x(a), y(b) {}
// Overload binary minus (-) operator
Point operator-(const Point& p) {
return Point(x - p.x, y - p.y);
}
};
💡 Usage:
Point p1(5, 4), p2(2, 1);
Point result = p1 - p2; // result will be (3, 3)
🔹 20) Operators with Date Class
In a Date class, operator overloading makes date arithmetic more intuitive.
✅ Example: Overload == and != in a Date class
class Date {
public:
int day, month, year;
Date(int d, int m, int y) : day(d), month(m), year(y) {}
bool operator==(const Date& other) {
return day == other.day && month == other.month && year ==
other.year;
}
bool operator!=(const Date& other) {
return !(*this == other);
}
};
🔹 21) Unary Operators
Unary operators work with only one operand and can also be overloaded.
✅ Example: Overload unary minus (-) to negate a Number
class Number {
public:
int value;
Number(int v) : value(v) {}
// Overload unary minus operator
Number operator-() {
return Number(-value);
}
};
💡 Usage:
Number n1(10);
Number n2 = -n1; // n2.value = -10
✅ Summary Table
Topic Description
Minus Operator Overload Customize subtraction for user-defined objects
Operators with Date Class Overload comparison or arithmetic operators for date handling
Unary Operator Overload Customize behavior of operators like -obj, ++obj, --obj
📘 Lecture 33: Operator Overloading & this Pointer
🔹 22) Operator Overloading (Recap)
• Operator overloading lets you redefine how operators work with user-defined types
(classes).
• Syntax:
ReturnType operatorSymbol(Parameter) { ... }
🔹 23) Assignment Operator (=)
• Used to copy values from one object to another.
• Must handle deep copy when the class involves dynamic memory.
✅ Example:
class MyClass {
int* data;
public:
MyClass(int value) {
data = new int(value);
}
// Overloading assignment operator
MyClass& operator=(const MyClass& other) {
if (this != &other) { // prevent self-assignment
delete data;
data = new int(*other.data);
}
return *this;
}
};
🔹 25) this Pointer
• this is an implicit pointer available in all non-static member functions.
• Points to the calling object.
✅ Usage:
class Sample {
public:
int x;
Sample(int x) {
this->x = x; // distinguish between parameter and member
}
};
🔹 26) Self Assignment
• Occurs when an object is assigned to itself, like obj = obj;.
• Can cause problems (like deleting memory before copying it).
• Always check:
if (this == &other) return *this;
🔹 27) Returning *this Pointer from a Function
• Used in operator overloading to allow chaining, like:
a = b = c;
✅ Example:
MyClass& operator=(const MyClass& other) {
if (this != &other) {
// copy logic
}
return *this;
}
🔹 28) Conversions
• You can define how one data type is converted into another using:
o Conversion constructors
o Conversion operator functions
🔹 29) Sample Program – Conversion by Constructor
✅ Example:
class MyClass {
int value;
public:
MyClass(int x) { value = x; } // constructor for conversion from int to
MyClass
};
💡 Usage:
MyClass obj = 10; // Implicitly calls MyClass(10)
✅ Summary Table
Concept Description
Assignment Operator Custom behavior for = operator
this Pointer Refers to current object instance
Self Assignment Check to avoid assigning object to itself
Returning *this Enables chained assignments
Conversion Constructor Automatically converts basic types to objects