Execution Order of Constructors & Destructors

The execution order of constructors and destructors in C++ is determined by the inheritance hierarchy and the object's lifetime. When you create an object, constructors are called in a specific order, and when the object goes out of scope or is explicitly deleted, destructors are called in the reverse order of construction. Here's how it works:

1. Constructors:

  1. Base Class Constructors: When an object of a derived class is created, the constructors of all its base classes are called first, starting with the base class closest to the derived class and proceeding to the base class closest to the root of the inheritance hierarchy. This order is known as the "top-down" or "base-to-derived" order.

  2. Derived Class Constructor: After the base class constructors have executed, the constructor of the derived class itself is called. This allows the derived class to perform its own initialization.

Here's an example to illustrate the constructor execution order:

class Base {
public:
    Base() {
        std::cout << "Base constructor" << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
    }
};

int main() {
    Derived obj;
    return 0;
}

Output:

Base constructor
Derived constructor

In this example, the base class constructor (Base) is called before the derived class constructor (Derived).

2. Destructors:

  1. Derived Class Destructor: When an object goes out of scope or is explicitly deleted, the destructor of the derived class is called first. This allows the derived class to perform its own cleanup operations.

  2. Base Class Destructors: After the derived class destructor has executed, the destructors of all its base classes are called in the reverse order of construction, starting from the base class closest to the derived class and proceeding to the base class closest to the root of the inheritance hierarchy. This order is known as the "bottom-up" or "derived-to-base" order.

Here's an example to illustrate the destructor execution order:

class Base {
public:
    Base() {
        std::cout << "Base constructor" << std::endl;
    }

    ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
    }

    ~Derived() {
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Derived obj;
    return 0;
}

Output:

Base constructor
Derived constructor
Derived destructor
Base destructor

In this example, the derived class destructor (Derived) is called before the base class destructor (Base), and this order follows the reverse order of construction.

Understanding the execution order of constructors and destructors is crucial for proper resource management and cleanup in complex class hierarchies. It ensures that resources are allocated and deallocated in the correct sequence.

Last updated

Was this helpful?