2011-04-26 17 views
5

Estoy leyendo un poco de texto en C++. En un ejemplo, el texto escrito:Pregunta sobre asignar el constructor predeterminado a * esto en C++?

class Student { 
    int no; 
    char grade[M+1]; 
public: 
    Student(); 
    Student(int, const char*); 
    const Student& set(int, const char*); 
    void display() const; 
}; 

Student::Student() { 
    no = 0; 
    grade[0] = '\0'; 
} 

Student::Student(int n, const char* g) { 
    *this = Student(); // initialize to empty 
    set(n, g);   // validate, reset if ok 
} 

No entiendo esta línea: *this = Student();

¿Por qué tenemos que hacer eso, mientras que sólo llamar Student(); también hace que el constructor por defecto invocado? Gracias

Respuesta

7

No se puede llamar directamente al constructor predeterminado (C++ FAQ). es decir.

Student::Student(int n, const char* g){ 
Student(); 
set(n, g); // validate, reset if ok 
} 

no funciona. Sin embargo, tampoco estoy seguro de la solución que tienes.

*this = Student() 

llamará Student::operator=(const Student&). En esta clase en particular, está bien (esa función es la copia de miembro predeterminada) pero puede que no sea en general, porque el objeto de Estudiante está 'parcialmente construido' cuando se llama a ese método.

mejor tener una función init privada

void Student::init() { 
no = 0;  
grade[0] = '\0'; 
} 

y lo llaman de ambos constructores.

1

Construye un objeto temporal Student y luego lo copia en *this. Sin embargo, me gustaría inicializar las variables miembro para vaciar en el segundo constructor. La idea es que no tiene que escribir el mismo código que inicializa las variables miembro como vacío dos veces, pero aquí es un problema bastante trivial.

+0

este es un mal consejo. La duplicación es mala. Donde es trivialmente evitable es especialmente imperdonable. Siga el código en la pregunta y cuando necesite extender la clase solo necesita agregar inicialización en un solo lugar. –

+0

También podría agregar un método privado init() para los valores predeterminados y llamarlo desde todos los constructores, ahorrando la sobrecarga de la construcción de un objeto temporal. – Torp

+0

bien, sé muy poco de los detalles de los constructores de C++. Pero sé que la duplicación del código es mala y si un inicio privado es la mejor manera de lograrlo, entonces es el camino a seguir. –

1

*this = Student(); es solo para inicializar las variables miembro con respecto al constructor predeterminado llamado. Tal diseño debe evitarse, ya que crea contenido temporal y lo copia.

usar algo como a continuación:

void reset() { // introduce this method inlined in the class 
    grade[no = 0] = '\0'; 
} 

Student::Student() { 
    reset(); // call it when needed 
} 

Student::Student(int n, const char* g) { 
    reset(); // initialize to empty 
    set(n, g);   // validate, reset if ok 
} 
3

Aunque, en mi humilde opinión, sería mejor utilizar la función de inicialización común, algo como esto:

class Student { 
    (...) 
    private: 
     void initMe(); 
}; 

Student::Student() { 
    initMe(); 
} 

Student::Student(int n, const char* g) { 
    initMe(); // initialize to empty 
    set(n, g);   // validate, reset if ok 
} 


void Student::initMe() { 
    no = 0; 
    grade[0] = '\0'; 
} 

que evitaría la creación innecesaria de objetos.

Cuestiones relacionadas