+ 7

[C++] Base and Derived classes constructor problem

I was doing another (private...) project and got stuck with an error. I have no idea what is that problem supposed to be. I made a simplified and generalized version of this part of code: https://code.sololearn.com/c4XqlKEu9F2b/?ref=app Can you, please, explain me: - Why does this error happen? - How to solve this error and prevent it in future?

15th Feb 2021, 9:54 AM
#0009e7 [get]
#0009e7 [get] - avatar
15 Answers
+ 12
The error happens because, as you might remember, the base class constructor is called before the derived class constructor upon instantiation of a derived object. If you don't do so explicitly via the member initialization list, the compiler will try to call the default base constructor. However, your base class only has a parameterized constructor, thus the compiler can not select a default constructor and construction fails. Depending on what you want, you basically have two options: 1) Add a default constructor to your base class, e.g. Base() = default; 2) Explicitly call a base constructor from the derived constructors, e.g. for the copy constructor Derived( const Derived& other ) : Base{ other.value } {}
15th Feb 2021, 10:19 AM
Shadow
Shadow - avatar
+ 8
Ipang I don't quite understand your issue, sorry. Everything I stated above also goes for the copy constructor, i.e. first the base part is constructed via a base class constructor and then the derived part via the actual derived constructor. Normally, the compiler automatically calls the default constructor if no explicit call is made from the member initialization list. However, "Base" has no default constructor (implicitly deleted), and the compiler can't figure out what to do on its own. Therefore, if you don't add a default constructor, you need to explicitly call another constructor. Actually, you could also call the base copy constructor: Derived( const Derived& other ) : Base{ static_cast< const Base& >( other ) } {}
15th Feb 2021, 12:26 PM
Shadow
Shadow - avatar
+ 7
Ipang The colon is just syntax for the member initialization list. This one: https://en.cppreference.com/w/cpp/language/constructor And instead of initializing a variable located in your derived class, you initialize the base class. In fact, if you don't call a base constructor explicitly like that, the following two are equivalent Derived( const Derived& other ) { this->value = other.value; } Derived( const Derived& other ) : Base() { this->value = other.value; } due to the way how instances are constructed, which also was the root of the original problem - there was no Base::Base() in the "Base" class the compiler could have called. But that does not mean any "Derived" constructor would return a "Base" instance, it's just part of the initialization process. At the end, you will get a "Derived" instance, which is what a constructor does, after all - it constructs an instance of its class.
15th Feb 2021, 3:32 PM
Shadow
Shadow - avatar
15th Feb 2021, 10:56 AM
Sonic
Sonic - avatar
+ 6
get Yeah, I remember the SL tutorial only touches on the initialization of variables this way. Well, I assume you mean declaration and definition. In that case, the list is part of the definition: struct Derived { Derived( const Derived& ); ... }; Derived::Derived( const Derived& other ) : Base{ other.value } {} A declaration usually only contains necessary identifiers, types, and attributes like const, no other 'actual' code. Ipang Sorry, I always think of you as an experienced C++ user, so I was a bit surprised when you asked. Therefore, my explanation might have been off in that way. As I said earlier, it's really very similar to variable initialization, only for those properties that are inherited. Assume for a second those properties were private - you would still want a way to initialize them from the derived class, and this is how you would do it. Anyway, I'm sure you'll be able to grasp it quickly after some sleep - maybe try writing a code yourself or look more into it on the web.
15th Feb 2021, 5:19 PM
Shadow
Shadow - avatar
+ 5
Shadow, thanks again, now have better understanding of colon and code between it and opening brace in the method definition than Sololearn C++ course explains! 😂 One more question: what about using this stuff when references and later full definitions are used? Are those colon and the code after it supposed to be in the reference or in the full definition (like with class inheritance)? (sorry that I write it not in the separate question, but I can make one)
15th Feb 2021, 4:35 PM
#0009e7 [get]
#0009e7 [get] - avatar
+ 4
Shadow First, Thank you for answering, I remember member initializer from the tutorial here. But this is the first time I see it used this way. I thought member initializer were meant to initialize members of the Derived class itself, rather than its base class (Base). I'm trying to grasp on it but now I'm a bit tired, and it looks hard to digest. I guess I have to read that again later maybe after sleep time.
15th Feb 2021, 4:49 PM
Ipang
+ 4
get Apology for the noises. I meant not to hijack your thread, just couldn't help the curiosity and confusion (still). Nice discussion topic BTW 👍
15th Feb 2021, 4:51 PM
Ipang
+ 4
Shadow I don't know if I should be proud or ashamed you thought of me as "experienced" LOL 😆 I hope you wouldn't mind me asking you more surprising questions in future, cause that, is very possible hehehe Yea I hope so too, but you know, most stuffs on the web don't go much into details, though I can live with that. I'd probably better off try to experiment on CPg later Thanks Shadow 🙏
15th Feb 2021, 5:49 PM
Ipang
+ 4
Ipang just be proud, lol.
15th Feb 2021, 7:13 PM
Sonic
Sonic - avatar
+ 4
Ipang you have nothing to be embarrassed about 😁
16th Feb 2021, 6:18 AM
Sonic
Sonic - avatar
+ 3
Shadow The colon here, what does it mean? : Base{ other.value } : Base { ( static_cast< const Base& > other ) } {} As I understand it, `Base( const Base& other )` return a `Base` instance? then does it mean `Derived( const Derived& other )` also return a `Base` instance? I'm just confused, sorry if my confirmation was unclear. I'm just wanting to understand.
15th Feb 2021, 1:25 PM
Ipang
+ 3
Sonic Now I'm really embarrassed LMAO 😂😂😂
16th Feb 2021, 2:04 AM
Ipang
+ 3
Sonic Idk, but OOP is pretty hard subject for me TBH I need to fix myself on that somehow 😁
16th Feb 2021, 6:43 AM
Ipang
+ 2
Shadow I don't understand option 2) Why we call `Base` copy constructor in the `Derived` copy constructor?
15th Feb 2021, 10:41 AM
Ipang