martes, 19 de junio de 2018

C++ Inicializador de miembros


OBJETOS Y FUNCIONES MIEMBRO CONST

En ocasiones, se debe evitar que los objetos puedan ser modificados, ya sea voluntariamente o por accidente. Además, los intentos de modificar un objeto, función o variable constante, se atrapan en tiempo de compilación. Con la palabra clave const, se especifica que un objeto, función o variable no puede ser modificada. Por ejemplo, la instrucción:

const Vertice angulo(45);

Declara un objeto const angulo, de la clase Vertice y lo inicia con el valor 45.
Declarar variables y objetos const, ayuda a mejorar el rendimiento, debido a que los compiladores optimizadores, pueden realizar ciertas tareas de rendimiento sobre las constantes, cosa que no pueden hacer sobre las que no lo son.
Hasta aquí, la teoría está bien, pero existe un problema que puede ocurrir con los constructores (o destructores) y es que un constructor al inicializar por ejemplo una variable, ésta debe ser modificada (para poder inicializarse), pero si la variable es const, entonces se producirá un error de compilación. Por ejemplo, vamos a ver el siguiente código:

#include<iostream>
using std::cout;

class Ejemplo{
   public:
    Ejemplo(){
      numero = 0;
    }
    void imprimir(){
      cout << "El valor a imprimir es: " << numero;
    }
   private:
    const int numero;
  };

int main(){

  Ejemplo prueba;
  prueba.imprimir();

return 0;
}

Podemos ver que el constructor de la clase Ejemplo, está inicializando la variable numero (numero = 0), que es una constante. Si trato de compilar el código, me arroja el siguiente error (en mi compilador)



Para solucionar este pequeño inconveniente, se utiliza lo que se conoce como inicializador de miembros. El inicializador de miembros, puede inicializar todos los datos miembro, pero los datos constantes deben inicializarse de esta manera. Además de que al utilizar la herencia (lo que se verá más adelante) también se utiliza el inicializador de miembros.
El inicializador, consiste en colocar dos puntos ( : ) luego del cierre de paréntesis del argumento del constructor (y antes de la apertura de llaves { ). Luego de los dos puntos, se debe poner el nombre de la variable, seguida del valor que la va a inicializar, el cual debe ir encerrada entre paréntesis. Esto quizás suene un poco enredado, pero en la práctica es muy sencillo, veamos como corregir el error del programa anterior.
Para corregir el problema, se debe modificar el constructor, el cual debe llevar el inicializador de miembros de esta manera:

    Ejemplo():numero(0){
      //cuerpo vacio (en este caso)
    }
Como se puede apreciar, luego de los dos puntos, se agregó la variable y luego el valor que la iniciará, quedando el cuerpo de las llaves vacío.
No es necesario que los puntos queden exactamente al lado del constructor, también puede quedar bajo este:

    Ejemplo()
    :numero(0){
      //cuerpo vacio (en este caso)
    }
 
    Ejemplo()
    :numero(0){}

    Ejemplo()
    :numero(0)
    {}

Si tuviese más valores que inicializar, estos se deben separar de una coma.

    Ejemplo()
    :numero(0), edad(20), otraEdad(15)
    {}

Si el constructor lleva argumentos, estos se deben inicializar de la siguiente manera:

    Ejemplo(arg1, arg2)
    :var1(arg1), var2(arg2)
    {}

 Espero se entienda. Saludos.
https://codigogx.blogspot.com/2018/06/c-destructores.html



Gustavo J. Cerda Nilo. Junio 2018
 


domingo, 10 de junio de 2018

C++ Destructores


C++ DESTRUCTORES

Un destructor, es un tipo de función especial que se complementa en cierto sentido a los constructores. Su misión es realizar las tareas de mantenimiento de terminación cuando un objeto es destruido y es llamado en forma implícita cuando esto ocurre.
Un destructor no recibe parámetros y no devuelve un valor. Tampoco puede especificar un tipo de valor de retorno; ni siquiera void. Una clase sólo puede tener un destructor, no se permite la sobrecarga de destructores y éstos deben ser public.
Todas las clases tienen un destructor, si no se especifica uno, entonces el compilador crea un destructor por defecto. Este destructor por defecto se crea vacío, es decir que no lleva ningún tipo de instrucción. Más adelante, al especificar nuestro destructor, le podremos agregar algunas instrucciones.
El nombre de un destructor es exactamente el mismo de la clase, precedido de un tilde (~)
Ejemplo:

class MiEjemplo{
    public:
            MiEjemplo(); //Constructor
            ~MiEjemplo(); //Destructor
};

A continuación se muestra un ejemplo en donde, al llamar al constructor y este al terminar su tarea, automáticamente llama a su destructor.

#include<iostream>
using std::cout;
using std::endl;

class Ejemplo{
  public:
    Ejemplo(){
      cout << "Se ejecuta el Constructor" << endl;
    }
    ~Ejemplo(){
      cout << "Se ejecuta el Destructor" << endl;
    }
};

int main(){
  Ejemplo imprimir;
return 0;
}

Al compilar y ejecutar este código, esto es lo que muestra:



El orden en el que ocurren estas llamadas a funciones depende del orden en el que la ejecución entra y sale de los alcances en los que se instancian los objetos. Por lo general, las llamadas a los destructores se realizan en orden inverso a las llamadas correspondientes a los constructores.
Los destructores correspondientes se llaman cuando termina la función main.
Esto es todo por ahora.
Saludos

Gustavo J. Cerda Nilo - Junio 2018
 
https://codigogx.blogspot.com/2018/06/c-envoltura-del-preprocesador.htmlhttps://codigogx.blogspot.com/2018/06/c-inicializador-de-miembros.html


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...