2010-02-20 18 views
7

Pensé que los constructores controlan la inicialización y operator = funciones controlan la asignación en C++. Entonces, ¿por qué funciona este código?Asignación vs Inicialización en C++

#include <iostream> 
#include <cmath> 
using namespace std; 

class Deg { 
    public: 
     Deg() {} 
     Deg(int a) : d(a) {}   
     void operator()(double a) 
     { 
      cout << pow(a,d) << endl; 
     } 

    private: 
     int d; 
}; 

int 
main(int argc, char **argv) 
{ 
    Deg d = 2; 
    d(5); 
    d = 3; /* this shouldn't work, Deg doesn't have an operator= that takes an int */ 
    d(5); 
    return 0; 
} 

En la tercera línea de la función principal, yo estoy asignando un int a un objeto de clase Deg. Como no tengo una función operator=(int), pensé que esto ciertamente fallaría ... pero en su lugar llama al constructor Deg(int a). Entonces, ¿los constructores también controlan la asignación?

Respuesta

18

Esto es lo que se llama conversión de tipo implícito. El compilador buscará si hay un constructor que cambie directamente del tipo que está asignando al tipo que está intentando asignar, y lo llamará. Se puede evitar que suceda mediante la adición de la palabra clave explicit delante del constructor que no le gustaría ser llamado implícitamente, como esto:

explicit Deg(int a) : d(a) {}

+0

+1 para explícita – dimba

+3

Al menos una empresa que he trabajado ha tenido en la regla de "uso explícito de todos los constructores a menos que haya una buena razón para no "entre sus estándares de codificación. Eso ayuda a evitar situaciones potencialmente misteriosas como esta. – Sean

+0

Supongo que te refieres a todos los constructores que se pueden invocar con un solo argumento :)? –

4

Solo para aclarar la respuesta de JonM:

Para el línea d = 3, un operador de asignación es involucrado. 3 se convierte implícitamente a Deg, como dijo JonM, y luego Deg tiene asignado a d usando el operador de asignación generado por el compilador (que por defecto hace una asignación de miembro). Si desea evitar la asignación, debe declarar un operador de asignación privada (y no ponerlo en práctica):

//... 
private: 
    Deg& operator=(const Deg&); 
} 
Cuestiones relacionadas