with explicit I tell the constructor that I don't want it to convert me, that is, that it either receives the exact parameters that it has to receive of the same type or it will give a compilation error.
So given the following class:
class Persona
{
public:
explicit Persona(int dnii = 00000000, int edadd = 00) : dni(dnii), edad(edadd) {}
void mostrarPersona() const;
private:
int dni;
int edad;
};
I can't do the following:
Persona p1 = 99999999; //Porque aquí convierto un entero a Persona
p1 = 11111111; //Porque aquí estoy asignando un entero a un tipo Persona
But instead, I can do this:
Persona p1 = Persona(12345678);
Persona p2(1234568);
My question is, why can I do those last instructions above?
If I'm not mistaken, this makes me an integer in Person with a temporary object and then makes its copy in p1:
Persona p1 = Persona(12345678);
In this case I am calling the conversion constructor that will convert me from integer to person, which I explicitly told it not to do:
Persona p2(1234568);
The specifier
explicit
marks a constructor (or since C++11 also conversion operators) so that it does not accept implicit conversions or copy initializations in its parameters.Implicit conversions.
C++ allows you to convert some types to each other automatically and transparently, these conversions are known as implicit conversions and are described in section 7 of the C++ standard (translation and emphasis mine):
What the standard says is that a type
A
can be implicitly converted toB
if the following code is correct:As we have already seen in another question , the code above will be correct if the type
B
has a constructor that it receivesA
as a parameter.int
implicitly convertible toPersona
.Let's use your class
Persona
as an example:In point 7.6 of the standard it tells us that this code...
...is equivalent to this...
...and that this is an implicit conversion. If you mark the constructor of
Persona
as youexplicit
will prohibit implicit conversions:In the case of
p2
no conversion, the copy constructor automatically defined by the compiler is called (as already explained in this question ).Because you are calling the (automatically generated by the compiler) copy constructor of
Persona
.In the proposed example:
If you are allowed the following instructions:
Because the compiler is allowed to resolve the constructor parameters and implicitly convert the integer value 99999999 to an object of type
Persona
with parameterdni
value 99999999 in the first case, and implicitly convert to an object of typePersona
withdni
99999999 andeddad
25 in the second.If we add the explicit specifier :
You are not allowed by the above statements because implicit conversion and copy initialization are not allowed. Nevertheless:
Yes, they are allowed, because you are assigning a type value to the type
p1
object , with parameter 1234568 and parameter 0.Persona
Persona
dni
edadd
The object
Persona(12345678)
is not aint
cast toPersona
, it is an objectPersona
with a parameter dni of typeint
with value 1234568 .In the second statement, there is a direct initialization to the
p2
type objectPersona
for the parameterdni
with the value 12345678 , but in neither case are you performing an implicit conversion between aint
andPersona
, rather you are directly assigning the value to the dni parameter.