C++ Constructors

Special methods for object initialization

🏗️ What are Constructors?

Constructors are special methods automatically called when objects are created. They initialize object data and set up the object's initial state without explicit calling.


class Person {
public:
    string name;
    int age;
    
    // Constructor
    Person(string n, int a) {
        name = n;
        age = a;
    }
};

Person person1("Alice", 25);  // Constructor called automatically
                                    

Result:

Person object created: Alice, age 25

Types of Constructors

🔧

Default Constructor

A default constructor has no parameters and initializes an object with predefined default values. It is automatically called when an object is created without arguments. This ensures the object is in a valid state from the start, even if no specific initialization data is provided. It's essential for creating arrays of objects and when using certain container classes.

Person() {
    name = "Unknown";
    age = 0;
}
⚙️

Parameterized

Takes parameters for initialization

Person(string n, int a) {
    name = n;
    age = a;
}
📋

Copy Constructor

A copy constructor creates a new object as an exact duplicate of an existing object, using a constant reference parameter. Declared as ClassName(const ClassName& other), it's automatically invoked when objects are copied—such as passing by value, returning from functions, or explicit assignment. This constructor is essential for classes managing dynamic memory, ensuring deep copies prevent issues like double-deletion and data corruption. Without a properly defined copy constructor, the compiler generates a shallow copy, potentially causing serious runtime errors and memory leaks in resource-heavy applications.

Person(const Person &p) {
    name = p.name;
    age = p.age;
}
🔄

Overloaded

Multiple constructors with different parameters

Person();
Person(string n);
Person(string n, int a);

🔹 Default Constructor

A default constructor has no parameters and initializes an object with predefined default values. It is automatically called when an object is created without arguments. This ensures the object is in a valid state from the start, even if no specific initialization data is provided. It's essential for creating arrays of objects and when using certain container classes.

#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;
    
    // Default constructor
    Car() {
        brand = "Unknown";
        model = "Unknown";
        year = 2000;
        cout << "Default constructor called!" << endl;
    }
    
    void displayInfo() {
        cout << "Car: " << brand << " " << model << " (" << year << ")" << endl;
    }
};

int main() {
    Car car1;  // Default constructor called
    car1.displayInfo();
    
    return 0;
}

Output:

Default constructor called!
Car: Unknown Unknown (2000)

🔹 Parameterized Constructor

Parameterized constructors accept arguments to initialize objects with specific, user-provided values, enabling flexible and customized object creation. Unlike default constructors, parameterized constructors allow you to pass data directly during instantiation, such as Rectangle(5, 3) to set width and height. This approach ensures each object starts in a meaningful state tailored to its purpose. For example, a Student("Alice", 20, 3.8) constructor initializes name, age, and GPA simultaneously. Parameterized constructors are fundamental in object-oriented programming, reducing the need for post-creation initialization and improving code clarity, maintainability, and reducing bugs from incomplete or invalid initial states.

class Rectangle {
public:
    double length;
    double width;
    
    // Parameterized constructor
    Rectangle(double l, double w) {
        length = l;
        width = w;
        cout << "Rectangle created: " << length << " x " << width << endl;
    }
    
    double calculateArea() {
        return length * width;
    }
    
    void displayInfo() {
        cout << "Length: " << length << ", Width: " << width << endl;
        cout << "Area: " << calculateArea() << endl;
    }
};

int main() {
    Rectangle rect1(5.0, 3.0);  // Parameterized constructor
    Rectangle rect2(10.0, 7.5);
    
    rect1.displayInfo();
    cout << endl;
    rect2.displayInfo();
    
    return 0;
}

Output:

Rectangle created: 5 x 3
Rectangle created: 10 x 7.5
Length: 5, Width: 3
Area: 15

Length: 10, Width: 7.5
Area: 75

🔹 Constructor Overloading

Constructor overloading enables defining multiple constructors with different parameter signatures within the same class, providing flexible object initialization. Each constructor can accept varying numbers and types of arguments, allowing objects to be created in multiple ways based on available data. For example, a Student class might have a constructor accepting only a name, another accepting name and age, and a third accepting all details including GPA. The compiler automatically selects the appropriate constructor based on the arguments provided at instantiation, enhancing usability and reducing the need for default or post-initialization setup.

class Student {
public:
    string name;
    int age;
    double gpa;
    
    // Default constructor
    Student() {
        name = "Unknown";
        age = 18;
        gpa = 0.0;
        cout << "Default constructor used" << endl;
    }
    
    // Constructor with name only
    Student(string n) {
        name = n;
        age = 18;
        gpa = 0.0;
        cout << "Name constructor used" << endl;
    }
    
    // Constructor with name and age
    Student(string n, int a) {
        name = n;
        age = a;
        gpa = 0.0;
        cout << "Name and age constructor used" << endl;
    }
    
    // Constructor with all parameters
    Student(string n, int a, double g) {
        name = n;
        age = a;
        gpa = g;
        cout << "Full constructor used" << endl;
    }
    
    void displayInfo() {
        cout << "Student: " << name << ", Age: " << age << ", GPA: " << gpa << endl;
    }
};

int main() {
    Student s1;                           // Default
    Student s2("Alice");                  // Name only
    Student s3("Bob", 20);               // Name and age
    Student s4("Charlie", 22, 3.8);      // All parameters
    
    s1.displayInfo();
    s2.displayInfo();
    s3.displayInfo();
    s4.displayInfo();
    
    return 0;
}

Output:

Default constructor used
Name constructor used
Name and age constructor used
Full constructor used
Student: Unknown, Age: 18, GPA: 0
Student: Alice, Age: 18, GPA: 0
Student: Bob, Age: 20, GPA: 0
Student: Charlie, Age: 22, GPA: 3.8

🔹 Copy Constructor

A copy constructor creates a new object as an exact duplicate of an existing object, using a constant reference parameter. Declared as ClassName(const ClassName& other), it's automatically invoked when objects are copied—such as passing by value, returning from functions, or explicit assignment. This constructor is essential for classes managing dynamic memory, ensuring deep copies prevent issues like double-deletion and data corruption. Without a properly defined copy constructor, the compiler generates a shallow copy, potentially causing serious runtime errors and memory leaks in resource-heavy applications.

class Point {
public:
    int x, y;
    
    // Default constructor
    Point(int xVal = 0, int yVal = 0) {
        x = xVal;
        y = yVal;
        cout << "Point created at (" << x << ", " << y << ")" << endl;
    }
    
    // Copy constructor
    Point(const Point &p) {
        x = p.x;
        y = p.y;
        cout << "Point copied to (" << x << ", " << y << ")" << endl;
    }
    
    void displayPoint() {
        cout << "Point: (" << x << ", " << y << ")" << endl;
    }
};

int main() {
    Point p1(3, 4);        // Parameterized constructor
    Point p2 = p1;         // Copy constructor
    Point p3(p1);          // Copy constructor (alternative syntax)
    
    p1.displayPoint();
    p2.displayPoint();
    p3.displayPoint();
    
    return 0;
}

Output:

Point created at (3, 4)
Point copied to (3, 4)
Point copied to (3, 4)
Point: (3, 4)
Point: (3, 4)
Point: (3, 4)

🧠 Test Your Knowledge

When is a constructor called?