Constructors and Destructors in C++

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

  1. Same name as the class
  2. No return type (not even void)
  3. Automatically called when an object is created
  4. Used to initialize object’s data members
  5. 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

  1. Same name as the class, preceded by a tilde (~)
  2. No return type and no parameters
  3. Cannot be overloaded (only one destructor per class)
  4. 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:

  1. A local object goes out of scope
  2. A program ends and global objects are destroyed
  3. An object created with new is deleted using delete
  4. A temporary object’s lifetime ends

Important Uses of Destructors

  1. Release dynamic memory: Free memory allocated with new
  2. Close files: Close any files opened by the object
  3. Release resources: Release any system resources acquired by the object
  4. Clean up: Perform any other necessary cleanup

Constructors vs. Destructors

ConstructorsDestructors
Called when objects are createdCalled when objects are destroyed
Same name as classSame name as class with ~ prefix
Can take parametersCannot take parameters
Can be overloadedCannot be overloaded
Used to initialize objectsUsed to clean up resources
Multiple constructors allowedOnly one destructor allowed

Best Practices

  1. Always initialize all data members in constructors
  2. Provide a default constructor when you define other constructors
  3. Free all dynamically allocated resources in the destructor
  4. Keep constructors and destructors simple
  5. 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.