Why does the C ++ copy constructor behave differently when invoking its child copy constructor?

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 did not provide a copy constructor for class B, the compiler would synthesize one for me, and that one would use the copy constructor that I provided for class A. However, if I provide a copy constructor for class B, where I do not explicitly call copy constructor for base class A (see code), will the compiler call the standard CONSTRUCTOR of class A? Why is this?

+4
source share
4 answers

When you write a constructor — any constructor — for a derived class, you can (and often should) explicitly initialize the base class subobjects in this list of constructor initializers. If you do not, the compiler will indirectly call the default constructors for these base class subobjects, assuming they are available. This rule applies to absolutely all custom constructors.

This is exactly what happened in your case. You forgot to initialize the base constructor A to B::B(const B&) , so the default constructor was used for this base. The fact that B::B(const B&) is a copy constructor does not matter in this case. It works the same way, sequentially, for all types of user-defined constructors.

Now, if you do not provide a custom copy constructor, the compiler will try to provide implicitly. An implicit copy constructor will attempt to invoke copy constructors for all base classes. The language specification simply says that such a constructor, created by the compiler, behaves in such a way that is the answer to your question “why”.

+1
source

This is standard behavior. This is mainly for consistency: any user-defined constructor that does not explicitly invoke a specific base class constructor will invoke the default value. Why is the copy constructor different?

+9
source

Initialization rules apply here. You can only replace this rule by providing your own constructor.

0
source

What you did not notice is that the element data is processed in the same way as the data of the base class : it is initialized by copying if the compiler provides a copy constructor, but initialized by default -construction if you are writing an instantiated constructor instance.

By implementing the copy constructor, you tell the compiler that you decide how the members and base classes will be initialized . In the absence of additional instructions from you, they will be initialized using the default method.

0
source

Source: https://habr.com/ru/post/1501197/


All Articles