I am studying TADs
in C++
, and in the constructor section I get to the list of inicializadores
, it is horribly explained and I have not found a video or page that explains it clearly.
What is the constructor initializer list for?
If in theory I can assign values to variables in the constructor implementation, I don't understand why (or in what case) it has to be specified before.
To answer this question, it is first necessary to clarify the concept of " life cycle " of a piece of data.
Lifecycle.
A datum exists from the time it is instantiated until it leaves the scope in which it was instantiated, for example:
int
In the code above, the called type variablei
begins its life cycle when it is defined (int i = 0;
) and when it leaves the scope in which it was defined (the functionmain
) it ends its life cycle. Let's look at another example:We see that the data is born when it is defined and dies when it leaves the scope in which it was defined. In the previous example, the function
main
has a sub-scope in which it defines a variable of typechar
calledc
that ends its life cycle before the data is born.f
of typefloat
because its scope ends just before definingf
.This sub-scope thing is what happens in loops
for
:When a piece of data is part of another object, its life cycle is the same as that of the object it is part of:
We are going to look in more detail at the data that is part of other objects, since their life cycle begins when the object they are part of is created, when we enter the body of the constructor these objects already exist... otherwise! we couldn't use them!:
If, when entering the constructor body, the data already existed, when did the life cycle begin? We can imagine that they were born between the definition of the constructor and the start of the scope of the constructor body:
Having clarified the life cycle of the sub-objects of an object, we can address the question...
What is the constructor initializer list for?
Sometimes you need to give value to sub-objects of a type at the moment they start their life cycle, this is known as initialization. There are certain types of data that necessarily need to be initialized, such as constants or references, so the following code does not compile:
Since it
S::entero_constante
is data qualified as a constant, it is not possible to modify its value when its life cycle has already begun. Since in C++ you cannot change the object that a reference is referencing, you need to assign value to references at the moment they start their life cycle, so the way we useS::referencia_a_entero
is incorrect 1 ; To solve this problem we must use the initializer list of the constructor:The constructor initializer list is also used to call the constructor on sub-objects that lack a default constructor:
Easy to fix:
The constructor initializer list is also used to call the constructor of the base class(es):
And (lastly) it is also used to delegate the construction to another constructor:
Summary.
The constructor initializer list is used to:
1 And because we try to reference a constant datum in a non-constant way.