What are Constructors?
A constructor is a special member function that is automatically called when an object of a class is created. It has the same name as the class and is used to initialize the object’s data members.
Think of a constructor as a setup process that prepares your object for use, like setting up a new phone with your preferences when you first turn it on.
Key Features of Constructors
- Same name as the class
- No return type (not even void)
- Automatically called when an object is created
- Used to initialize object’s data members
- Can be overloaded (multiple constructors with different parameters)
Simple Constructor Example
#include <iostream>
using namespace std;
class Student {
private:
string name;
int rollNumber;
public:
// Constructor
Student() {
name = "Unknown";
rollNumber = 0;
cout << "Constructor called: Student created" << endl;
}
void display() {
cout << "Name: " << name << ", Roll Number: " << rollNumber << endl;
}
};
int main() {
Student s1; // Constructor is automatically called here
s1.display();
return 0;
}
Types of Constructors
1. Default Constructor
A constructor that takes no parameters. It can be either:
- Provided by the compiler if no other constructor is defined
- Explicitly defined by the programmer
class Box {
private:
double length, width, height;
public:
// Default constructor
Box() {
length = 1.0;
width = 1.0;
height = 1.0;
}
double volume() {
return length * width * height;
}
};
2. Parameterized Constructor
A constructor that takes parameters to initialize objects with specific values.
class Rectangle {
private:
double length;
double width;
public:
// Parameterized constructor
Rectangle(double l, double w) {
length = l;
width = w;
}
double area() {
return length * width;
}
};
int main() {
Rectangle rect(5.0, 3.0); // Create rectangle with length 5 and width 3
cout << "Area: " << rect.area() << endl; // Output: Area: 15
return 0;
}
3. Copy Constructor
A constructor that creates a new object as a copy of an existing object.
class Point {
private:
int x, y;
public:
// Parameterized constructor
Point(int a, int b) {
x = a;
y = b;
}
// Copy constructor
Point(const Point &p) {
x = p.x;
y = p.y;
cout << "Copy constructor called" << endl;
}
void display() {
cout << "Point: (" << x << ", " << y << ")" << endl;
}
};
int main() {
Point p1(10, 20); // Uses parameterized constructor
Point p2 = p1; // Uses copy constructor
Point p3(p1); // Also uses copy constructor
p1.display(); // Output: Point: (10, 20)
p2.display(); // Output: Point: (10, 20)
return 0;
}
Constructor Overloading
A class can have multiple constructors with different parameter lists (same as function overloading).
class Student {
private:
string name;
int rollNumber;
float marks;
public:
// Default constructor
Student() {
name = "Unknown";
rollNumber = 0;
marks = 0.0;
}
// Constructor with name and roll number
Student(string n, int r) {
name = n;
rollNumber = r;
marks = 0.0;
}
// Constructor with all details
Student(string n, int r, float m) {
name = n;
rollNumber = r;
marks = m;
}
void display() {
cout << "Name: " << name << ", Roll: " << rollNumber << ", Marks: " << marks << endl;
}
};
int main() {
Student s1; // Uses default constructor
Student s2("John", 101); // Uses constructor with 2 parameters
Student s3("Alice", 102, 95.5); // Uses constructor with 3 parameters
s1.display();
s2.display();
s3.display();
return 0;
}
What are Destructors?
A destructor is a special member function that is automatically called when an object is destroyed or goes out of scope. It is used to free resources that the object may have acquired during its lifetime.
Think of a destructor as a cleanup process, like closing all applications and saving your work before shutting down your computer.
Key Features of Destructors
- Same name as the class, preceded by a tilde (~)
- No return type and no parameters
- Cannot be overloaded (only one destructor per class)
- Automatically called when an object is destroyed
Destructor Example
#include <iostream>
using namespace std;
class Student {
private:
string name;
int* rollNumber; // Dynamic memory
public:
// Constructor
Student(string n, int r) {
name = n;
rollNumber = new int; // Allocate memory
*rollNumber = r;
cout << "Constructor called for " << name << endl;
}
// Destructor
~Student() {
cout << "Destructor called for " << name << endl;
delete rollNumber; // Free allocated memory
}
void display() {
cout << "Name: " << name << ", Roll: " << *rollNumber << endl;
}
};
int main() {
Student s1("John", 101);
s1.display();
{ // Create a block
Student s2("Alice", 102);
s2.display();
} // s2 is destroyed here when it goes out of scope
cout << "End of main" << endl;
return 0; // s1 is destroyed here
}
Output:
Constructor called for John
Name: John, Roll: 101
Constructor called for Alice
Name: Alice, Roll: 102
Destructor called for Alice
End of main
Destructor called for John
When are Destructors Called?
Destructors are automatically called when:
- A local object goes out of scope
- A program ends and global objects are destroyed
- An object created with
newis deleted usingdelete - A temporary object’s lifetime ends
Important Uses of Destructors
- Release dynamic memory: Free memory allocated with
new - Close files: Close any files opened by the object
- Release resources: Release any system resources acquired by the object
- Clean up: Perform any other necessary cleanup
Constructors vs. Destructors
| Constructors | Destructors |
|---|---|
| Called when objects are created | Called when objects are destroyed |
| Same name as class | Same name as class with ~ prefix |
| Can take parameters | Cannot take parameters |
| Can be overloaded | Cannot be overloaded |
| Used to initialize objects | Used to clean up resources |
| Multiple constructors allowed | Only one destructor allowed |
Best Practices
- Always initialize all data members in constructors
- Provide a default constructor when you define other constructors
- Free all dynamically allocated resources in the destructor
- Keep constructors and destructors simple
- Avoid calling virtual functions in constructors and destructors
Summary
Constructors and destructors are special member functions that handle the creation and destruction of objects. Constructors initialize objects when they are created, while destructors clean up resources when objects are destroyed. They are essential components of classes in C++ and play a crucial role in resource management and maintaining object integrity throughout its lifecycle.