Reputation: 671
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
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
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:
A
with default value for m_i
2B
member m_a1
with value based on initialized m_i
B
member m_a2
with value from argument 5and destruction is as follows:
B
m_a2
m_a1
A
Which translates to:
m_i
m_i
m_a2
m_a1
m_i
Upvotes: 0
Reputation: 4838
2531
is a correct answer. The order of calling destructors is always opposed to the order of calling constructors.
2
- destructor of B5
,3
- destructors of class fields in order opposed to the order of initializing1
- destructor of super classsee: Order of member constructor and destructor calls
Upvotes: 1