Constructors, destructors and operator overloading notes — Unit 2
Free unit-wise study notes on constructors, destructors and operator overloading 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 exploration of Object Lifecycle Management and Semantic Extensions. Covers Constructors, Destructors, Copy Semantics, and Operator Overloading to build intuitive, powerful C++ classes.
Notebook — 14 pages
Page 1
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
1. The Object Lifecycle
Just like any physical entity, every object in C++ goes through a definitive lifecycle: Creation, Usage, and Destruction. To manage this lifecycle securely, C++ provides special member functions.
⇒Why do we need special functions?
When you create an integer `int x;`, it contains garbage value. When you create an object `BankAccount acc;`, it also contains garbage. If `balance` is a garbage value, any deposit or withdrawal is invalid. We need a guaranteed mechanism to initialize objects the moment they are created.
Memory Allocation
OS allocates physical RAM for the object's variables.
Initialization (Constructor)
Special function executes automatically to set valid initial states.
Usage
Application calls methods to interact with the object.
Cleanup (Destructor)
Special function executes to release resources before memory is reclaimed.
Deallocation
OS reclaims the physical RAM.
Page 2
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
2. Introduction to Constructors
A Constructor is a special member function whose task is to initialize the objects of its class. It is special because its name is the EXACT same as the class name.
⇒Strict Rules for Constructors
Name Matching: Must have the exact same name as the class itself.
No Return Type: Not even `void`. A constructor returns nothing because its job is strictly memory initialization.
Automatic Execution: It is invoked automatically when the object is created. You do not call it explicitly.
Public Access: They should generally be declared in the `public` section. If private, objects cannot be created from outside the class.
Basic Constructor Implementation
class Server {
int port;
string ip;
public:
// Constructor
Server() {
port = 8080;
ip = "127.0.0.1";
cout << "Server object initialized!";
}
};
int main() {
Server s1; // "Server object initialized!" is printed instantly
}
Page 3
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
3. Default Constructor
C++ allows multiple constructors in a single class through Function Overloading. This gives flexibility in how an object can be initialized.
⇒1. The Default Constructor
A constructor that accepts no parameters. If you do not write ANY constructor, the C++ compiler automatically generates a hidden, empty default constructor for you. But if you write ANY constructor with parameters, the compiler STOPS generating the default one.
class Point {
int x, y;
public:
// Default Constructor
Point() {
x = 0;
y = 0;
}
};
int main() {
Point p; // Invokes default constructor
// Point p(); // WARNING: This is a function declaration, not an object!
}
Page 4
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
4. Parameterized Constructors
⇒2. The Parameterized Constructor
A constructor that takes arguments. It allows you to pass specific initial values when the object is created.
Passing arguments during creation
class Rectangle {
int length, breadth;
public:
// Parameterized Constructor
Rectangle(int l, int b) {
length = l;
breadth = b;
}
};
int main() {
// Implicit Call
Rectangle r1(10, 5);
// Explicit Call
Rectangle r2 = Rectangle(10, 5);
}
⇒Dynamic Initialization
Parameterized constructors are powerful because they allow 'Dynamic Initialization'. You can prompt the user for input at runtime, and only THEN create the object using those specific inputs.
Page 5
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
5. Constructor Overloading
Because constructors are just functions, they can be overloaded. A class can have a default constructor, multiple parameterized constructors, and a copy constructor, all coexisting.
class Complex {
float real, imag;
public:
Complex() { real = 0; imag = 0; } // Default
Complex(float r) { real = r; imag = 0; } // One parameter
Complex(float r, float i) { real = r; imag = i; } // Two params
};
int main() {
Complex c1; // Calls Default
Complex c2(5.5); // Calls One parameter
Complex c3(2.0, 3.5); // Calls Two params
}
⇒Constructors with Default Arguments
Instead of overloading multiple constructors, you can write a single constructor with default arguments to achieve the same result.
class Complex {
float real, imag;
public:
// Covers 0, 1, or 2 parameters!
Complex(float r = 0, float i = 0) {
real = r; imag = i;
}
};
Page 6
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
6. The Initializer List
In C++, assigning values inside the constructor body is actually 'assignment', not 'initialization'. True initialization happens BEFORE the body executes. For peak performance, C++ offers the Initializer List.
Syntax of Initializer List
class Entity {
int id;
const string name;
public:
// Initializer list comes after a colon
Entity(int i, string n) : id(i), name(n) {
// Body can be empty!
}
};
⇒When is the Initializer List MANDATORY?
Constant Data Members: `const` variables must be initialized at creation. They cannot be assigned inside the body.
Reference Members: References (`&`) must be bound to a variable immediately upon creation.
Base Class Constructors: To pass arguments to a parent class constructor, you MUST use the initializer list in the derived class.
Object Members without Default Constructors: If your class contains another object as a member, and that object lacks a default constructor, you must initialize it here.
Page 7
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
7. The Copy Constructor
⇒3. The Copy Constructor
A copy constructor is used to declare and initialize an object from another existing object of the SAME class. It essentially clones the object.
If you don't write a copy constructor, C++ provides a default one. This default copy constructor performs a Shallow Copy (a literal bit-by-bit copy of the variables).
⇒The Danger of Shallow Copies
If your class contains pointers to dynamically allocated memory on the heap, a shallow copy is disastrous. Both the original and the copied object will have pointers pointing to the EXACT SAME memory address.
Object A [ ptr ] ---> [ Heap Memory Block ]
Object B [ ptr ] -------^ (Points to same block!)
Shallow Copy Crash Scenario
If Object A is destroyed, it frees the heap memory. Object B's pointer now points to freed memory (a dangling pointer). If Object B tries to free it again, the program crashes (Double Free Error).
⇒The Deep Copy Solution
To fix this, you MUST write your own custom Copy Constructor to perform a Deep Copy. You allocate brand new heap memory for the clone, and then copy the data over.
String(const String &source) {
int len = strlen(source.str);
str = new char[len + 1]; // Allocate NEW memory
strcpy(str, source.str); // Copy data
}
Page 9
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
9. Destructors
Just as constructors prepare an object for use, Destructors clean up an object before its memory is destroyed.
⇒Rules for Destructors
Name Matching: It has the exact same name as the class, prefixed by a tilde `~`.
No Parameters & No Return Type: It takes no arguments and returns nothing.
Cannot be Overloaded: Because it takes no arguments, there can be ONLY ONE destructor per class.
Automatic Execution: It is automatically called when the object goes out of scope (e.g., function ends, or `delete` is called on a pointer).
Destructors are critical for Resource Acquisition Is Initialization (RAII). Whenever an object acquires a resource (memory, file handle, network port, database lock), the destructor MUST release it to prevent resource leaks.
Page 10
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
10. Operator Overloading Basics
Operator Overloading is one of C++'s most powerful features. It allows you to redefine how standard operators (`+`, `-`, `*`, `==`) work when applied to user-defined objects.
⇒The Goal of Overloading
To make custom classes behave like built-in types. Instead of writing `c3 = c1.add(c2);` for complex numbers, we want to write `c3 = c1 + c2;`.
⇒Syntax of Operator Overloading
We use the special `operator` keyword followed by the symbol we want to overload.
Unary operators operate on a single operand (e.g., `-x`, `++x`, `!x`). When overloaded as a member function, they take NO arguments, because the calling object itself is the operand.
Overloading the Unary Minus (-)
class Vector3D {
int x, y, z;
public:
Vector3D(int a, int b, int c) : x(a), y(b), z(c) {}
// Unary minus reverses the vector
void operator-() {
x = -x;
y = -y;
z = -z;
}
};
int main() {
Vector3D v(10, -5, 3);
-v; // Invokes v.operator-()
}
⇒Prefix vs Postfix Increment (++)
To distinguish between `++obj` (prefix) and `obj++` (postfix), C++ introduces a dummy `int` parameter for the postfix version.
Binary operators operate on two operands (e.g., `A + B`). When overloaded as a member function, they take EXACTLY ONE argument. The calling object is the left operand, and the argument is the right operand.
Expression: `A + B` ====> translates to ====> `A.operator+(B)`
There are situations where overloading via a member function is impossible. For instance, what if the left operand is NOT an object of your class?
⇒The Integer Multiplication Problem
For a Vector class, `Vector v2 = v1 5;` translates to `v1.operator(5)`. This works perfectly as a member function. BUT what about `Vector v2 = 5 v1;`? This translates to `5.operator(v1)`, which is illegal because `5` is a primitive integer, not an object!
To fix this, we overload the operator using a Friend Function. A friend function takes BOTH operands as explicit arguments.
Using Friend Functions for Commutativity
class Vector {
int val;
public:
Vector(int v) : val(v) {}
// Friend declaration takes two args
friend Vector operator*(int scalar, const Vector &v);
};
// Definition outside
Vector operator*(int scalar, const Vector &v) {
return Vector(scalar * v.val);
}
int main() {
Vector v1(10);
Vector v2 = 5 * v1; // Now this works perfectly!
}
Page 14
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 2 —
14. Unit 2 Revision Checklist
⇒End-of-Unit Verification
Explain the exact moment a constructor is called and list its 4 main rules.
Write the syntax for a parameterized constructor and explain dynamic initialization.
Identify the 'Vexing Parse' error when trying to create an object with a default constructor.
Explain why a Copy Constructor MUST take its argument by reference (`&`).
Draw the memory diagram showing the catastrophic difference between Shallow Copy and Deep Copy.
List the 4 scenarios where an Initializer List is absolutely mandatory.
Explain RAII and the role of Destructors in preventing memory leaks.
Write the syntax to overload the `++` operator in both Prefix and Postfix forms.
List the 5 operators in C++ that cannot be overloaded.
Explain why overloading the stream operators (`<<` and `>>`) MUST be done using Friend functions, not member functions.