I have the following toy class A and its child B:
#include <iostream>
using namespace std;
class A
{
protected:
int a;
public:
A():a(1){cout<<"A default constructor..."<<endl;}
A(int i):a(i){cout<<"A non-default constructor..."<<endl;}
A(const A &ao){cout<<"A copy constructor..."<<endl; a=ao.a;}
};
class B:public A
{
private:
int b;
public:
B(int i,int j):A(i),b(j){cout<<"B constructor..."<<endl;}
//B(const B &bo){cout<<"B copy constructor... "<<endl; b=bo.b;}
void print(){cout<<endl<<"class B, a: "<<a<<" b: "<<b<<endl<<endl;}
};
int main()
{
B b1(3,8);
b1.print();
B b2=b1;
b2.print();
}
I found that if I don't provide a copy constructor for class B, the compiler will synthesize one for me, and that one uses the copy constructor I provided for class A. However, if I do provide a copy constructor for class B, where I don't explicitly call the copy constructor for the base class A (see code), the compiler will call the default CONSTRUCTOR of class A? Why is that?
This is the standard behavior. It's mostly for consistency: any user-defined constructor that doesn't explicitly call a specific base class constructor will call the default one. Why would the copy constructor be different?
When you write a constructor - any constructor - for a derived class you can (and often must) explicitly initialize base class subobjects in that constructor's initializer list. If you fail to do that, then the compiler will implicitly call the default constructors for those base class subobjects, assuming they are available. This rule applies to absolutely all user-defined constructors.
This is exactly what happened in your case. You forgot to initialize base A
in B::B(const B&)
's constructor, so the default constructor was used for that base. The fact that B::B(const B&)
is a copy constructor makes no difference whatsoever in this case. It works that way, again, consistently for all kinds of user-defined constructors.
Now, if you do not provide a user-defined copy constructor, then the compiler will attempt to provide on implicitly. The implicitly-defined copy constructor will attempt to call copy constructors for all base classes. The language spec just says that compiler-provided copy constructor behaves that way, which is the answer to your "why" question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With