[c++]: problem about initiation list in constructor
-
09-01-2021 - |
Question
I stumbled across a question that I never thought about before. Here it is: each object's (listed in the initialization list) "constructor" will be triggered.
class B
{
public:
B() { cout<<"B Con\n";}
B(const B &b) { cout<<"B Copy Con\n";}
};
class A
{
public:
A(B &b):_m(b) { cout<<"A Con\n";}
A(const A &a):_m(a._m) { cout<<"A Copy Con\n";}
private:
B _m;
}
main()
{
B b;
A a(b);
}
then I got the output as follows:
B Con
B Copy Con
A Con
According to the output, I think, 'A a(b)' triggered B's copy constructor. If I got right, then that means 'A(B &b):_m(b)' triggers B's copy constructor. Why not constructor but copy-constructor?
Solution
The reason is when you call
_m( whatever )
then the copy constructor
B(const B &b)
is the only one that could match the parameter list. You pass it one parameter and that parameter is of type class B
.
Copy constructor is not something super special - it is just a parameterized constructor that will be invoked via the initialization list once the parameter list matches.
OTHER TIPS
Because you're telling the compiler to initialize _m
with b
, how would that not call the copy constructor?
The answer lies in the A(B &b):_m(b)
You are instantiating B _m with the copy constructor.
If instead you did A(B &b):_m()
it would use the default constructor.
A(B &b):_m(b) { cout<<"A Con\n";}
Here _m(b)
causes invocation of B(const B&)
which is B's copy-constructor. That is why, it first prints B Copy Con
when initializing _m
, then it enters into A's constructor body, and prints A Con
. That explains it all.