Home C++ Constructors in C+ tutorial with code examples

Constructors in C+ tutorial with code examples

Constructors in C++ are special member functions that are automatically called when an object of a class is created. They initialize the object’s data members and allow setting up initial values when creating an instance.

Key Characteristics of Constructors

  • Same name as the class: Constructors have the same name as the class they belong to.
  • No return type: Constructors do not have a return type, not even void.
  • Called automatically: Constructors are called automatically when an object is created.
  • Overloading: Constructors can be overloaded, allowing multiple ways to initialize an object.

Types of Constructors

  1. Default Constructor: A constructor with no parameters.
  2. Parameterized Constructor: A constructor with parameters, allowing specific initial values.
  3. Copy Constructor: A constructor that creates a copy of an existing object.
  4. Constructor with Default Arguments: A constructor with default values for parameters.

Let’s go through each type with examples.

1. Default Constructor

A default constructor is a constructor with no parameters. It initializes objects with default values.

#include <iostream>
using namespace std;

class Car {
public:
    string make;
    string model;
    int year;

    // Default Constructor
    Car() {
        make = "Unknown";
        model = "Unknown";
        year = 0;
        cout << "Default constructor called!" << endl;
    }

    void displayInfo() {
        cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl;
    }
};

int main() {
    Car car1; // Default constructor is called
    car1.displayInfo();

    return 0;
}

Explanation:

  • The default constructor Car() sets make, model, and year to default values.
  • When Car car1; is executed, the default constructor initializes car1.

Output:

Default constructor called!
Make: Unknown, Model: Unknown, Year: 0

2. Parameterized Constructor

A parameterized constructor accepts parameters to initialize the object with specific values.

#include <iostream>
using namespace std;

class Car {
public:
    string make;
    string model;
    int year;

    // Parameterized Constructor
    Car(string m, string mo, int y) {
        make = m;
        model = mo;
        year = y;
        cout << "Parameterized constructor called!" << endl;
    }

    void displayInfo() {
        cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl;
    }
};

int main() {
    Car car1("Toyota", "Camry", 2020); // Parameterized constructor is called
    car1.displayInfo();

    return 0;
}

Explanation:

  • Car(string m, string mo, int y) is a parameterized constructor that initializes make, model, and year.
  • When Car car1(“Toyota”, “Camry”, 2020); is called, the parameterized constructor sets the specified values.

Output:

Parameterized constructor called!
Make: Toyota, Model: Camry, Year: 2020

3. Copy Constructor

A copy constructor creates a new object as a copy of an existing object. The default copy constructor performs a shallow copy, but you can define your own copy constructor.

#include <iostream>
using namespace std;

class Car {
public:
    string make;
    string model;
    int year;

    // Parameterized Constructor
    Car(string m, string mo, int y) {
        make = m;
        model = mo;
        year = y;
        cout << "Parameterized constructor called!" << endl;
    }

    // Copy Constructor
    Car(const Car &c) {
        make = c.make;
        model = c.model;
        year = c.year;
        cout << "Copy constructor called!" << endl;
    }

    void displayInfo() {
        cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl;
    }
};

int main() {
    Car car1("Toyota", "Corolla", 2021); // Parameterized constructor is called
    Car car2 = car1;                      // Copy constructor is called
    car2.displayInfo();

    return 0;
}

Explanation:

  • Car(const Car &c) is a copy constructor that creates a copy of car1 in car2.
  • When Car car2 = car1; is executed, the copy constructor initializes car2 with car1’s data.

Output:

Parameterized constructor called!
Copy constructor called!
Make: Toyota, Model: Corolla, Year: 2021

4. Constructor with Default Arguments

A constructor with default arguments allows optional parameters. If an argument isn’t provided, the default value is used.

#include <iostream>
using namespace std;

class Rectangle {
private:
    int length;
    int width;

public:
    // Constructor with default arguments
    Rectangle(int l = 5, int w = 10) {
        length = l;
        width = w;
    }

    int area() {
        return length * width;
    }
};

int main() {
    Rectangle rect1;           // Uses default arguments
    Rectangle rect2(8, 12);    // Uses provided arguments

    cout << "Area of rect1: " << rect1.area() << endl;
    cout << "Area of rect2: " << rect2.area() << endl;

    return 0;
}

Explanation:

  • Rectangle(int l = 5, int w = 10) allows you to create a rectangle with default dimensions if no arguments are passed.
  • Rectangle rect1; uses default values, while Rectangle rect2(8, 12); uses specified values.

Output:

Area of rect1: 50
Area of rect2: 96

5. Overloaded Constructors

C++ allows overloading constructors by defining multiple constructors with different parameter lists, enabling different ways to initialize an object.

#include <iostream>
using namespace std;

class Box {
private:
    int length;
    int width;
    int height;

public:
    // Default constructor
    Box() {
        length = 1;
        width = 1;
        height = 1;
    }

    // Parameterized constructor for custom dimensions
    Box(int l, int w, int h) {
        length = l;
        width = w;
        height = h;
    }

    int volume() {
        return length * width * height;
    }
};

int main() {
    Box box1;               // Calls default constructor
    Box box2(3, 4, 5);      // Calls parameterized constructor

    cout << "Volume of box1: " << box1.volume() << endl;
    cout << "Volume of box2: " << box2.volume() << endl;

    return 0;
}

Explanation:

  • Box() and Box(int l, int w, int h) are overloaded constructors.
  • Box box1; calls the default constructor, while Box box2(3, 4, 5); calls the parameterized constructor.

Output:

Volume of box1: 1
Volume of box2: 60

6. Member Initialization List in Constructors

Member initialization lists allow initializing members directly and are especially useful for const and reference members.

#include <iostream>
using namespace std;

class Person {
private:
    const string name;
    int age;

public:
    // Constructor with member initialization list
    Person(string n, int a) : name(n), age(a) {}

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person person("Alice", 30);
    person.display();

    return 0;
}

Explanation:

  • Person(string n, int a) : name(n), age(a) initializes name and age directly.
  • Member initialization is necessary for const members like name.

Output:

Name: Alice, Age: 30

7. Dynamic Memory Allocation in Constructors

Constructors can allocate dynamic memory using pointers, but you should also provide a destructor to free the memory.

#include <iostream>
using namespace std;

class Array {
private:
    int *data;
    int size;

public:
    // Constructor with dynamic memory allocation
    Array(int s) {
        size = s;
        data = new int[size];
        for (int i = 0; i < size; i++) {
            data[i] = i + 1;
        }
    }

    // Destructor to free allocated memory
    ~Array() {
        delete[] data;
    }

    void display() {
        for (int i = 0; i < size; i++) {
            cout << data[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    Array arr(5);
    arr.display();

    return 0;
}

Explanation:

  • The constructor Array(int s) allocates dynamic memory using new.
  • The destructor ~Array() releases the allocated memory with delete[].

Output:

1 2 3 4 5

8. Constructor Delegation

In C++11 and later, constructors can call each other

, a feature known as constructor delegation.

#include <iostream>
using namespace std;

class Rectangle {
private:
    int length;
    int width;

public:
    // Default constructor
    Rectangle() : Rectangle(1, 1) {} // Calls the parameterized constructor

    // Parameterized constructor
    Rectangle(int l, int w) : length(l), width(w) {}

    int area() {
        return length * width;
    }
};

int main() {
    Rectangle rect1;        // Calls default constructor
    Rectangle rect2(4, 5);  // Calls parameterized constructor

    cout << "Area of rect1: " << rect1.area() << endl;
    cout << "Area of rect2: " << rect2.area() << endl;

    return 0;
}

Explanation:

  • Rectangle() delegates to Rectangle(int l, int w) with default dimensions.
  • rect1 uses delegated values, while rect2 uses specific values.

Output:

Area of rect1: 1
Area of rect2: 20

Summary Table of Constructor Types

Constructor Type Description Example
Default Constructor Initializes object with default values ClassName()
Parameterized Constructor Initializes object with specified values ClassName(int x)
Copy Constructor Creates a new object as a copy of an existing object ClassName(const ClassName &obj)
Constructor with Default Arguments Constructor with parameters having default values ClassName(int x = 10)
Overloaded Constructors Multiple constructors with different parameter lists ClassName(), ClassName(int x)
Member Initialization List Initializes members directly (useful for const and references) ClassName(int x) : member(x) {}
Dynamic Memory Allocation Allocates memory with new in the constructor ClassName() { ptr = new int[n]; }
Constructor Delegation One constructor calls another within the same class ClassName() : ClassName(10) {}

Complete Example with Multiple Constructors

This example combines multiple constructor types, including default, parameterized, and copy constructors.

#include <iostream>
using namespace std;

class Box {
private:
    int length;
    int width;

public:
    // Default constructor
    Box() : length(1), width(1) {
        cout << "Default constructor called." << endl;
    }

    // Parameterized constructor
    Box(int l, int w) : length(l), width(w) {
        cout << "Parameterized constructor called." << endl;
    }

    // Copy constructor
    Box(const Box &b) : length(b.length), width(b.width) {
        cout << "Copy constructor called." << endl;
    }

    int area() const {
        return length * width;
    }
};

int main() {
    Box box1;                  // Default constructor
    Box box2(5, 10);           // Parameterized constructor
    Box box3 = box2;           // Copy constructor

    cout << "Area of box1: " << box1.area() << endl;
    cout << "Area of box2: " << box2.area() << endl;
    cout << "Area of box3: " << box3.area() << endl;

    return 0;
}

Sample Output:

Default constructor called.
Parameterized constructor called.
Copy constructor called.
Area of box1: 1
Area of box2: 50
Area of box3: 50

Constructors in C++ are essential for object initialization and enable flexibility through overloading and copy construction.

You may also like