user1279988
user1279988

Reputation: 763

C++ constructor & destructor order

I am trying a code about base class and member construction and destruction and I am confused about some order of constuctor and destructor, the output of this code is:

Base1 constructor
Member1 constructor
Member2 constructor
Derived1 constructor
Member3 constructor
Member4 constructor
Derived2 constructor
Derived2 destructor
Member4 destructor
Member3 destructor
Derived1 destructor
Member2 destructor
Member1 destructor
Base1 destructor

See the first four line, but I fell the order should be

Base1 constructor
Derived1 constructor
Member1 constructor
Member2 constructor

Anyone can give me some explain?

#include "stdafx.h"
#include <fstream>
using namespace std;
ofstream out("order.out");

#define CLASS(ID) class ID { \
public: \
  ID(int) { out << #ID " constructor\n"; } \
  ~ID() { out << #ID " destructor\n"; } \
};

CLASS(Base1);
CLASS(Member1);
CLASS(Member2);
CLASS(Member3);
CLASS(Member4);

class Derived1 : public Base1 {
  Member1 m1;
  Member2 m2;
public:
  Derived1(int) : m2(1), m1(2), Base1(3) {
    out << "Derived1 constructor\n";
  }
  ~Derived1() {
    out << "Derived1 destructor\n";
  }
};

class Derived2 : public Derived1 {
  Member3 m3;
  Member4 m4;
public:
  Derived2() : m3(1), Derived1(2), m4(3) {
    out << "Derived2 constructor\n";
  }
  ~Derived2() {
    out << "Derived2 destructor\n";
  }
};

int main() {
  Derived2 d2;
} ///:~

Upvotes: 12

Views: 2858

Answers (5)

Praveen Vinny
Praveen Vinny

Reputation: 2408

Consider the following program which will make your idea clear!

#include<iostream.h>
class A
{
public:
  A()
    {
    cout<<"\nI am the base class constructor!";
    }
  ~A()
    {
    cout<<"\nI am the base class destructor!";
    }
};

class B : public A
{
public:
  B()
    {
    cout<<"\nI am the derived class constructor!";
    }
  ~B()
    {
    cout<<"\nI am the derived class destructor!";
    }
};

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

The output of the above program will be as follows..

I am the base class constructor!

I am the derived class constructor!

I am the derived class destructor!

I am the base class destructor!

I think this explains and clarifies your query about the order of invocation of the constructors and destructors.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258558

Constructors are called upwards in the hierarchy:

- base class member objects
- base class constructor body
- derived class member objects
- derived class constructor body

The output is correct.

Let's simplify your code:

struct BaseMember
{
   BaseMember() { cout << "base member" <<endl; }
};
struct Base
{
   BaseMember b;
   Base() { cout << "base" << endl; }
};
struct DerivedMember
{
   DerivedMember() { cout << "derived member" << endl; }
};
struct Derived : public Base
{
   DerivedMember d;
   Derived() { cout << "derived" << endl; }
};

Derived d;

When d is created, it will first create the Base part. Before it enters the constructor body, all member objects are initialized. So BaseMember is the first object initialized.

Next, the constructor of Base is entered.

Before, the constructor of Derived enters, member objects of Derived are initialized, so DerivedMember is created, next Derived constructor is called.

This happens because when you enter the constructor body of a derived class, base classes and member objects must be completely initialized.

EDIT As Matthieu pointed out, the order in which the member objects are initialized is specified by the order in which they appear in the class definition, not the order in which they appear in the initializer list.

Upvotes: 10

Stuart Golodetz
Stuart Golodetz

Reputation: 20616

Well the initialisation done in the initialisation list happens before the body of the Derived1 constructor, so you see the output for m1 and m2 first.

As a more complete answer, what happens is this: first base sub-objects are constructed, then members are constructed in order of their declaration in the class (not their order in the initialisation list), then the constructor body is executed. Destruction happens in reverse order.

In this case, when you construct a Derived2, it first goes to construct the Derived1 sub-object. This in turn involves first constructing the Base sub-object, so it does that first. It then constructs the members of Derived1, executes the body of the Derived1 constructor, constructs the members of Derived2 and finally executes the body of the Derived2 constructor. Hence the observed output.

Upvotes: 1

Pavel Strakhov
Pavel Strakhov

Reputation: 40492

Constructor of the class executes later than constructors of its fields. Constructor of base class and all its members executes earlier than constructor of derived class and its members.

Upvotes: 2

Gordon Bailey
Gordon Bailey

Reputation: 3911

This is simply because m1 and m2 are initialized in the initialization list of the Derived1 constructor. Everything in the initialization list is constructed before the body of the constructor is entered.

Upvotes: 1

Related Questions