Constructores y Destructores de POO

Cada vez que se define una variable de un tipo básico, el programa ejecuta un procedimiento que se encarga de asignar la memoria necesaria, y si es necesario, también realizará las inicializaciones pertinentes. Los constructores y destructores de POO se aprecian de forma complementaria cuando una variable queda fuera de ámbito. Luego, se llama a un procedimiento que libera el espacio que estaba ocupando dicha variable.

 

El método al que se llama cuando creamos una variable es el constructor, y al que se llama cuando se destruye una variable es el destructor.

Una clase puede tener uno o varios constructores, pero un sólo destructor. El constructor debe tener el mismo nombre que la clase a la que pertenece, mientras que el destructor también debe llamarse de igual forma pero precedido por el carácter.

Te Puede Interesar…

Welcome to your Proceso de Selección

Name (Nombre)
Email (Correo)
Country (Pais)
City (Ciudad)
Occupation (Ocupacion)

Estos métodos no van a tener parámetros de salida, ni siquiera puede usarse void.
Sin embargo, el constructor sí podría tomar parámetros de entrada, cosa que no puede hacer el destructor.

Al haber creado un constructor que toma un parámetro – la cadena a asignar a la cadena que se está declarando-, ya no es posible crear un objeto de clase Cadena sin ese parámetro. Puesto que es posible tener varios constructores, estamos usando sobrecarga.

También se puede tener un constructor que por ejemplo inicialice a nulo todos los datos miembros de la clase.

Constructor de Copia y Asignación

En el ejemplo anterior, se observa que el operador de concatenación devuelve un objeto de la clase Cadena a fin de que ese valor de retorno se asigne a algún objeto de la forma C3=C1+C2. Sin embargo, no se ha definido el operador = para esta clase, y esto va a funcionar a pesar de ello porque por defecto el operador = hace una copia bit a bit. Por el contrario sí va a haber problemas cuando ocurra que el operando de destino (C2=C1) apunte a alguna dirección de memoria y con esta asignación se pierda. Para evitar este problema, se usa el constructor de copia y asignación, definiendo el método operator=(). Sin embargo, hay a veces un problema con este operador que nos lleva a que tengamos que sobrecargarlo.

Si se ejecuta el programa de la figura 5 paso a paso, se verá que para crear e inicializar los objetos C3 y C4 se usa el constructor de copia, mientras que en la asignación C3=C2 se llama al método operator=(). También observará que el programa llama a veces al constructor de copia sin causa aparente, esto es porque dicho constructor también se utiliza para crear objetos temporales por parte del programa, por ejemplo para pasar un objeto de una función a otra.

Constructor de Conversión

A veces es necesario usar un objeto de una determinada clase en una expresión que no está preparada para él, y habrá que realizar conversiones (casting).

Pueden ocurrir dos casos:
a) Que se asigne a un objeto de nuestra clase otro que no lo es.
b) Que se asigne a un objeto de otra clase otro de la nuestra.

Ej.: Tenemos una definición del siguiente tipo:

Cadena C1;
C1=“Hola, mundo”,

Esto sí es correcto, porque estamos asignando a C1 un char *, que sería la cadena “Hola, mundo”, que será lo que reciba como parámetro el constructor de la clase Cadena:

Cadena(char *Str);
Sin embargo no sería correcto:
Cadena C1;
Fecha Hoy;
C1=Hoy;

Esto no sería correcto hasta que no se cree un constructor que recibiendo un objeto de la clase Fecha cree un objeto de la clase Cadena. En el otro caso, es decir, convertir un dato de nuestra clase en otro tipo, hay que sobrecargar los operadores de moldeado o casts.

Por ejemplo, si queremos mostrar por pantalla la cadena de caracteres que tiene un objeto, así como su longitud, no podríamos hacer cout<<C1, sino que tendríamos que específicar el tipo básico de datos que queremos mostrar, es decir, debemos hacer lo siguiente: cout<<(char *) C1; cout<<(int) C1;

Destructores

El destructor, como se mencionó antes, se distingue del resto de miembros de una clase porque va precedido por el carácter ∼ . Cada vez que un objeto deja de ser útil, se llamará al destructor del objeto, que realizará sobre éste las últimas operaciones que sean necesarias. Si no se provee de un destructor se creará uno por defecto, que destruirá el objeto, sin tener en cuenta posibles liberaciones de memoria.

 

Cualquier destructor no puede aceptar parámetros ni de entrada ni de salida, y además sólo puede aparecer a lo sumo uno en cada clase.

Asignación Dinámica de Memoria

Se llama Asignación Dinámica de Memoria al proceso mediante el cual, se va reservando memoria a medida que vaya haciendo falta, y se va liberando cuando ya no sea útil. Algunos ejemplos son los vistos antes con new y delete.

Un objeto también se puede crear explícitamente por medio del operador new, que asignará la memoria necesaria para contener al objeto y devolverá un puntero al objeto en cuestión.

Ej.: Cadena *C=new Cadena;

El operador new siempre va seguido de un parámetro que indica el tipo de objeto que se quiere crear. De este parámetro, new obtiene el número de bytes necesarios para almacenar el objeto, y a continuación buscará un bloque de memoria apropiado, lo asigna al programa y devuelve su dirección. En este caso, accederemos a los miembros de la clase mediante el operador ->, y por medio de * accedemos al contenido. Lo que ocurre es que un objeto creado con new no se destruirá automáticamente cuando quede fuera de su ámbito, sino que ha de usarse para liberar memoria el comando delete. Al crear un objeto con new detrás del nombre de la clase se le puede hacer una asignación poniéndola entre paréntesis.

Errores en Asignación de Memoria

El operador new devuelve la dirección de memoria reservada para el objeto que se crea, pero esto lo hará siempre y cuando no haya problemas. Si no hay memoria suficiente devolverá un valor NULL. Por tanto, para controlar tales tipos de problemas lo que podemos hacer es crearnos una función que los trate.

 

Esto puede automatizarse en C++ usando la función set_new_handler() a la que se le pasará como parámetro el nombre de la función que maneja el error. Es necesario para poder usarlo incluir el fichero cabecera new.h
void ControlErroresdeMemoria()
{
cout<<“Error en asignación dinámica \n”;
exit(-1);
}
void main()
{
set_new_handler(ControlErroresdeMemoria);
Cadena *Q=new Cadena[32000];
}

Sobrecarga de New y Delete en los Constructores y Destructores de POO

  • El operador new, así como el delete, se pueden sobrecargar y así particularizar su funcionamiento dentro de una clase
  • new toma como parámetro size_t, indicando el tamaño del objeto a crear, y devuelve un puntero de tipo void
  • Delete, por su parte, recibe un puntero void y no devuelve nada
  • Además de new y delete, también podemos utilizar malloc() o free().
    CONSTRUCTORES
    aprendeinformaticas

tutorialesprogramacionya