Site icon Afzal Badshah, PhD

Constructors in C++ (Object-Oriented Programming)

When we create an object in C++, we expect it to start in a valid and usable state. In real life, a student record is not useful unless the university has stored the student’s name and roll number. Similarly, a car in a showroom is not meaningful unless it has a model and an engine number. In programming, the mechanism that ensures this proper initial state of an object is called a constructor.

A constructor guarantees that as soon as an object is created, it is properly initialized and ready to be used.

 A special member function of a class that is automatically called
when an object is created. Its main purpose is to initialize the object.

A constructor has the following characteristics:

• It has the same name as the class.

• It has no return type (not even void).

• It executes automatically when an object is created.

• It is mainly used to initialize data members of the class.

The Need for Constructors

In C++, when memory is allocated for an object, the data members may contain garbage values if they are not explicitly initialized. Using such uninitialized data can cause unpredictable behavior in programs.

Consider a student management system. If a Student object is created without initializing the name and roll number, the system may display incorrect or meaningless information. Therefore, initialization at the time of object creation is essential.

We can summarize this idea as:

Object Creation = Memory Allocation + Initialization

Constructors ensure that initialization happens immediately after memory allocation.

Default Constructor

A default constructor is a constructor that does not take any parameters. It assigns default or safe values to the data members.

A constructor that takes no parameters and initializes an object with default values.

Example: Student Class with Default Constructor

#include <iostream>
using namespace std;

class Student {
public:
    string name;
    int rollNo;

    Student() {
        name = "Unknown";
        rollNo = 0;
    }

    void display() {
        cout << "Name: " << name << endl;
        cout << "Roll No: " << rollNo << endl;
    }
};

int main() {
    Student s1;
    s1.display();
    return 0;
}

When the statement Student s1; is executed, the constructor runs automatically and initializes the data members. As a result, the object is created in a consistent and predictable state.

Parameterized Constructor

In many situations, we want to initialize objects with specific values at the time of creation. For example, when registering a student, the university already knows the student’s name and roll number.

A constructor that accepts parameters to initialize an object with specific values.

Example: Student Class with Parameterized Constructor

#include <iostream>
using namespace std;

class Student {
public:
    string name;
    int rollNo;

    Student(string n, int r) {
        name = n;
        rollNo = r;
    }

    void display() {
        cout << "Name: " << name << ", Roll No: " << rollNo << endl;
    }
};

int main() {
    Student s1("Ali", 101);
    Student s2("Sara", 102);

    s1.display();
    s2.display();
    return 0;
}

In this example, each object is initialized with meaningful data at the time of creation.

Constructor Overloading

A class may require multiple ways to create objects. For example, sometimes we may want to create a student with default values, and sometimes with complete information.

Defining multiple constructors in the same class
with different parameter lists.

Example: Overloaded Constructors

class Student {
public:
    string name;
    int rollNo;

    Student() {
        name = "Unknown";
        rollNo = 0;
    }

    Student(string n, int r) {
        name = n;
        rollNo = r;
    }
};

Now objects can be created in two different ways:

Student s1;                // Default constructor
Student s2("Hassan", 205); // Parameterized constructor

This improves flexibility and usability of the class.

Using the this Keyword in Constructors

Sometimes the parameter names are the same as the data member names. In such cases, the this pointer is used to refer to the current object.

A pointer that refers to the calling object of the class.

Example

class Student {
public:
    string name;
    int rollNo;

    Student(string name, int rollNo) {
        this->name = name;
        this->rollNo = rollNo;
    }
};

Here, this->name refers to the data member of the class, while name refers to the constructor parameter.

Constructor and Encapsulation

In well-designed programs, data members are usually kept private. Constructors help initialize private data properly.

Example: Car Class with Private Data

#include <iostream>
using namespace std;

class Car {
private:
    string model;
    string engineNo;

public:
    Car(string m, string e) {
        model = m;
        engineNo = e;
    }

    void display() {
        cout << "Model: " << model << endl;
        cout << "Engine No: " << engineNo << endl;
    }
};

int main() {
    Car c1("Toyota Corolla", "ENG12345");
    c1.display();
    return 0;
}

In this design, the constructor ensures that every Car object has valid model and engine number information at creation time.

Constructors in Inheritance

When inheritance is used, the constructor of the base (parent) class is executed before the constructor of the derived (child) class.

Order of Constructor Execution:
Base Class Constructor → Derived Class Constructor

Example

#include <iostream>
using namespace std;

class Vehicle {
public:
    Vehicle() {
        cout << "Vehicle constructor called" << endl;
    }
};

class Car : public Vehicle {
public:
    Car() {
        cout << "Car constructor called" << endl;
    }
};

int main() {
    Car c1;
    return 0;
}

When the Car object is created, the Vehicle constructor executes first, followed by the Car constructor.

Exit mobile version