viernes, 28 de octubre de 2016

Capítulo 80: Constructores en C++


Diario de un programador. Día 182

Constructores en C++

Al igual que en Java, en C++ también se pueden utilizar constructores.
Un constructor es un tipo de función que tiene por finalidad inicializar los objetos o variables con algún valor válido, para evitar que estos se inicialicen con su valor predeterminado, todo esto con la finalidad de evitar algún posible error.
Un constructor debe definirse con el mismo nombre que su clase, no devuelven ningún tipo de valor (ni siquiera void) y por lo general se declaran como public.
Si una clase no incluye un constructor, el compilador en forma interna crea uno con valores predeterminados.
El código estudiado en el capítulo 75 (tutorial anterior de c++), no posee un constructor y a pesar de que ese programa funciona, las buenas prácticas de programación (según lo que leí en la web) indican que siempre se debe crear un constructor. El código mostrado en esa oportunidad, es el siguiente:

#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::getline;

class Antecedentes{

private:
    string nombre;
    int edad;

public:
    void setNombre(string nom){
        nombre = nom;
    }
    void setEdad(int ed){
        edad = ed;
    }

    string getNombre(){
        return nombre;
    }
    int getEdad(){
        return edad;
    }

    void informe(){
        cout << "Nombre: " << getNombre() << endl;
        cout << "Edad: " << getEdad() << endl;
    }
};

int main(void){

    string nombreUsuario;
    int edadUsuario;

    Antecedentes datos;

    cout << "Ingresa tu nombre: ";
    getline(cin, nombreUsuario);
    cout << "Ingresa tu edad: ";
    cin >> edadUsuario;

    datos.setNombre(nombreUsuario);
    datos.setEdad(edadUsuario);
    datos.informe();

return 0;

}


Este código, lo que hace es solicitar un nombre y una edad, para luego imprimirlo en pantalla. Si a este código le agregamos un constructor, quedaría así:

#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::getline;

class Antecedentes{

private:
    string nombre;
    int edad;


public:

    Antecedentes(){//constructor
      nombre = "";
      edad = 0;
    }

    void setNombre(string nom){
        nombre = nom;
    }
    void setEdad(int ed){
        edad = ed;
    }

    string getNombre(){
        return nombre;
    }
    int getEdad(){
        return edad;
    }

    void informe(){
        cout << "Nombre: " << getNombre() << endl;
        cout << "Edad: " << getEdad() << endl;
    }
};

int main(void){

    string nombreUsuario;
    int edadUsuario;

    Antecedentes datos;

    cout << "Ingresa tu nombre: ";
    getline(cin, nombreUsuario);
    cout << "Ingresa tu edad: ";
    cin >> edadUsuario;

    datos.setNombre(nombreUsuario);
    datos.setEdad(edadUsuario);
    datos.informe();

return 0;
}

He destacado el código correspondiente al constructor:

    Antecedentes(){//constructor
      nombre = "";
      edad = 0;
    }

Como se puede apreciar, este constructor tiene el mismo nombre de su clase, no tiene un valor de retorno y su tarea en este caso es inicializar un par de variables. La variable nombre la inicializó con unas comillas dobles, mientras que la variable edad fue inicializada a cero. De esta forma, cada variable queda inicializada.
Para inicializar un objeto, hay que agregar ciertos parámetros. A continuación un ejemplo, utilizando el mismo código anterior, pero agregando algunos parámetros.

#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::getline;

class Antecedentes{

private:
    string nombre;
    int edad;

public:

    Antecedentes(string nombre, int edad){ //constructor
      setNombre(nombre); //llama a la funcion set para inicializar el nombre
      setEdad(edad); //llama a la funcion set para inicializar la edad
    }

    void setNombre(string nom){
        nombre = nom;
    }
    void setEdad(int ed){
        edad = ed;
    }

    string getNombre(){
        return nombre;
    }
    int getEdad(){
        return edad;
    }
};

int main(void){

    Antecedentes datos("Gus", 36);

    cout << "Nombre: " << datos.getNombre() << endl;
    cout << "Edad: " << datos.getEdad() << endl;
return 0;
}


En este caso el constructor recibe dos argumentos, uno de tipo string y uno de tipo int

    Antecedentes(string nombre, int edad){ //constructor

En este caso necesita de estos dos parámetros, debido a que en este constructor se van a inicializar dos variables locales, correspondiente a las funciones setNombre y setEdad.

setNombre(nombre); //llama a la funcion set para inicializar el nombre
setEdad(edad); //llama a la funcion set para inicializar la edad

Posteriormente, al crear un nuevo objeto, este debe llevar como argumento los datos que se utilizarán para inicializar las variables de las funciones setNombre y setEdad.

Antecedentes datos("Gus", 36);
Las últimas dos líneas realizan una llamada implícita al constructor inicializando los objetos.

    cout << "Nombre: " << datos.getNombre() << endl;
    cout << "Edad: " << datos.getEdad() << endl;

Hay que tener en cuenta que cualquier constructor que no lleve argumentos, se le conoce como constructor predeterminado
Recordar siempre proporcionar un constructor para asegurar que los miembros de datos de las clases se inicialicen con valores significativos.
Es una buena práctica asegurarse que un objeto se inicialice antes que el código invoque a las funciones.
Esto es todo por ahora. Saludos

Gustavo J. Cerda Nilo
Septiembre 2016, Octubre 2016



No hay comentarios:

Publicar un comentario

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...