int main() {
int theInt = 5;
/**
* Constructor "Example(int val)" in effect at the statement below.
* Same as "Example exObject(theInt);" or "Example exObject = Example(theInt);"
*/
Example exObject = theInt; // 1
Example ctr(5);
/**
* "operator unsigned int()" in effect at the statement below.
* What gets assigned is the value returned by "operator unsigned int()".
*/
int theInt1 = ctr; // 2
return 0;
}
En la instrucción 1 se llama al constructor Example(int val)
. Declararlo como explicit Example(int val)
y obtendrá un error de tiempo de compilación, es decir, no se permitirá ninguna conversión implícita para este constructor.
Todos los constructores de un único argumento se llaman implícitamente si el valor asignado es de su tipo de argumento respectivo. El uso de la palabra clave explicit
antes de los constructores de un solo argumento inhabilita la invocación implícita del constructor y, por lo tanto, la conversión implícita.
Si el constructor se declaró explícito, es decir, explicit Example(int val)
, sucedería lo siguiente para cada instrucción.
Example exObject(theInt); // Compile time error.
Example exObject = theInt; // Compile time error.
Example exObject(Example(theInt)); // Okay!
Example exObject = Example(theInt); // Okay!
También tenga en cuenta que en caso de llamada al constructor implícito y la conversión por lo tanto implícito el valor asignado es un valor p es decir,un objeto sin nombre implícitamente creado usando un valor-i (Theint) que nos dice que en el caso de la conversión implícita del compilador convierte
Example exObject = theInt;
a
Example exObject = Example(theInt);
Por lo tanto (en C++ 11) Don' Espere que se llame al constructor lvalue, ya que está utilizando un lvalue, es decir, un valor con nombre theInt
para la asignación. Lo que se llama es el constructor de rvalue ya que el valor asignado es en realidad el objeto sin nombre creado utilizando lvalue. Sin embargo, esto se aplica si tiene versiones lvalue y rvalue del constructor.
En la declaración 2 operator unsigned int()
se llama. Simplemente considérelo como una llamada a función normal con un nombre extraño y el hecho de que se puede llamar automágicamente cuando ocurre una conversión implícita. El valor devuelto por esa función es el valor asignado en la expresión. Y dado que en su implementación, el valor devuelto es una int, se asigna correctamente a int theInt1
.
Para ser precisos operator unsigned int()
sobrecargas ()
operador que es el operador de reparto. En su caso, está sobrecargado para int
, por lo tanto, cada vez que se asigna un objeto de la clase Example
a int
, se produce el vaciado de tipo implícito de Example
a int
y, por lo tanto, se llama a operator unsigned int()
. Por lo tanto,
int theInt1 = ctr;
es equivalente a
int theInt1 = (int)ctr;
@Zuzu: Me he dado cuenta que ha 'using namespace std;' cerca de la parte superior del archivo. Supongo que su profesor o material de enseñanza lo tiene así. Por casualidad no lo necesita en este ejemplo, pero tenga cuidado donde lo usa. ** Nunca ** nunca lo use en un archivo de cabecera; puede causar un dolor indescriptible si desea usar nombres que se encuentren en el espacio de nombres 'std'. Considere nunca usarlo en absoluto, pero si es como yo, puede usarlo solo en módulos (archivos .cpp) y, después de todo, #includes, pero antes de las definiciones de funciones y métodos. – quamrana
¿Cuál es tu pregunta? –