oneday
oneday

Reputation: 671

Member variables clearing while using destructor

I was going through some online quiz on C++ and below is the question I bumped into

http://www.interqiew.com/ask?ta=tqcpp01&qn=3

class A
{
public:
    A(int n = 2) : m_i(n) { }

    ~A() { std::cout << m_i; }

protected:
    int m_i;
};

class B
    : public A
{
public:
    B(int n) : m_a1(m_i + 1), m_a2(n) { }

public:
    ~B()
    {
        std::cout << m_i;
        --m_i;
    }

private:
    A m_a1;
    A m_a2;
};

int main()
{
    { B b(5); }

    std::cout << std::endl;

    return 0;
}

Answer comes out to be "2531" -

I was expecting the answer to be "21" - with rationale as below (which seems to be faulty):

Object B is created with three member variables with starting value 2 - 253

So when the destructor would be called would be deleted in reverse order.

For this case here destructor will call inherited part - we print 2 we decrement the value and go to 1 and then base while removing would be printed - so answer 21

How are variables m_a2 and m_a1 getting printed - not able to understand. Also its getting printed ( value 53) in the base part ( i.e. Class A)

Upvotes: 2

Views: 1825

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311146

Let's consider the constructor:

B(int n) : m_a1(m_i + 1), m_a2(n) { }

It is equivalent to:

B(int n) : A(), m_a1(m_i + 1), m_a2(n) { }

So at first m_i is initialized by the default argument of the constructor A and will be equal to 2. Then m_a1 will be initialized by m_i + 1, that is, it will be equal to 3. And at last m_a2 will be equal to 5 for the call of B( 5 )

Then when the destructor of B will be called it outputs:

std::cout << m_i;

That is:

2

and then decreases m_i:

--m_i;

Destructors of the data members are called in the reverse order relative to their constructions. So at first there will be called the destructor for m_a2 and it will output:

5

then there will be called the destructor for m_a1 and it will output:

3

and at last there will be called the destructor of the base class that will output:

1

So you will get:

2531

As for your question then the destructor of A is called three times: two times when data members m_a1 and m_a2 of class B are being destroyed (because they have type class A) and when the base class constructor is called.

Upvotes: 4

jaggedSpire
jaggedSpire

Reputation: 4523

I believe the destructors of member objects are each called after the specified destructor function, in reverse of their declaration order within the class, and then the destructors of the base objects are called.

So the order of the construction is this:

  1. Construct base class A with default value for m_i 2
  2. Construct B member m_a1 with value based on initialized m_i
  3. construct B member m_a2 with value from argument 5

and destruction is as follows:

  1. Execute destructor body for B
  2. Destruct m_a2
  3. Destruct m_a1
  4. Destruct base class A

Which translates to:

  1. print m_i
  2. decrement m_i
  3. print m_a2
  4. print m_a1
  5. print m_i

Upvotes: 0

Piotr Siupa
Piotr Siupa

Reputation: 4838

2531 is a correct answer. The order of calling destructors is always opposed to the order of calling constructors.

  • 2 - destructor of B
  • 5,3 - destructors of class fields in order opposed to the order of initializing
  • 1 - destructor of super class

see: Order of member constructor and destructor calls

Upvotes: 1

Related Questions