c++inheritancedestructor

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)


Solution

  • 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.