Ingeniería en comunicaciones y electrónica
Tema 2.2.3 del Plan de Estudios de POO IPN
STEAMdiantes en la POO, así como damos la bienvenida a un objeto con un constructor, también debemos despedirlo adecuadamente. Aquí es donde entra en escena el destructor. Si el constructor es el encargado de la “construcción y configuración”, el destructor es el equipo de “limpieza y demolición” que se asegura de que un objeto no deje un desorden cuando su vida llega a fin.
Un destructor es una función miembro especial que se llama automáticamente justo antes de que un objeto sea destruido. Esto sucede en varios escenarios, como cuando una variable local sale de su ámbito (por ejemplo, al finalizar una función), o cuando eliminamos explícitamente un objeto creado en memoria dinámica con el operador delete.
Su misión principal es liberar los recursos que el objeto pudo haber adquirido durante su vida. El recurso más común es la memoria dinámica, pero también puede tratarse de archivos abiertos, conexiones de red o bases de datos.
Características
Puedes reconocer a un destructor por sus reglas sintácticas, que son muy estrictas:
Mismo nombre que la clase, pero con una tilde (~) al inicio: Si la clase se llama Robot, su destructor se llamará ~Robot. Esta tilde (virgulilla) es el símbolo universal de la destrucción en C++.
No tiene tipo de retorno: Al igual que el constructor, no devuelve nada, ni siquiera void.
No acepta parámetros: Un destructor nunca recibe argumentos. Solo puede haber un destructor por clase.
Importancia
Imagina que tu objeto Robot necesita un componente especial que requiere memoria adicional, la cual solicitas usando el operador new. Esta memoria se asigna en una zona llamada heap (memoria dinámica).
Si olvidas liberar esa memoria cuando el objeto Robot ya no es necesario, esa memoria se queda “ocupada” y tu programa no puede volver a usarla. A esto se le llama fuga de memoria (memory leak). Una pequeña fuga puede no ser un problema, pero si creas y destruyes muchos objetos, estas fugas se acumulan y pueden hacer que tu programa consuma toda la memoria disponible y falle.
El destructor es el lugar perfecto y seguro para colocar el código que libera esos recursos.
Ejemplo
Veamos una clase Robot que tiene un arreglo dinámico para almacenar sus registros de misiones.
#include <iostream>
class Robot {
public:
std.string nombre;
int* registros_misiones; // Un puntero a un arreglo de enteros
// Constructor: Adquiere recursos (memoria dinámica)
Robot(std.string n) {
nombre = n;
// Solicitamos memoria para 5 registros
registros_misiones = new int[5];
std::cout << nombre << ": ¡Listo para la acción! Memoria para registros asignada." << std::endl;
}
// Destructor: Libera los recursos
~Robot() {
// Usamos delete[] porque creamos un arreglo con new int[5]
delete[] registros_misiones;
std::cout << nombre << ": Misión cumplida. Liberando memoria de registros." << std::endl;
}
};
void simularMision() {
std::cout << "--- Iniciando simulación de misión ---" << std::endl;
// Creamos un robot dentro del ámbito de esta función
Robot robot_alpha("Alpha-7");
// ... aquí el robot haría sus tareas ...
std::cout << "--- Simulación de misión terminada ---" << std::endl;
// Al finalizar la función, 'robot_alpha' sale del ámbito y su destructor es llamado.
}
int main() {
simularMision();
std::cout << "\n--- Creando un robot en el heap ---" << std::endl;
Robot* robot_beta = new Robot("Beta-9");
// ... usamos el robot ...
std.cout << "--- Eliminando robot del heap ---" << std.endl;
delete robot_beta; // Llamamos a delete, lo que invoca al destructor.
return 0;
}Analicemos la salida del código.
Si ejecutas este programa, la salida será algo como:
--- Iniciando simulación de misión ---
Alpha-7: ¡Listo para la acción! Memoria para registros asignada.
--- Simulación de misión terminada ---
Alpha-7: Misión cumplida. Liberando memoria de registros.
--- Creando un robot en el heap ---
Beta-9: ¡Listo para la acción! Memoria para registros asignada.
--- Eliminando robot del heap ---
Beta-9: Misión cumplida. Liberando memoria de registros.
Observa cómo por cada mensaje de “memoria asignada” hay un correspondiente mensaje de “liberando memoria”. Esto confirma que nuestros destructores están haciendo su trabajo, previniendo fugas de memoria y asegurando que nuestro programa sea robusto y eficiente.
Aunque a veces pueda parecer un concepto secundario, el destructor es un pilar de la gestión de recursos en C++. Es tu póliza de seguro contra las fugas de memoria y otros problemas relacionados con recursos. Acostúmbrate a pensar en el ciclo de vida completo de tus objetos: si un constructor adquiere un recurso, el destructor debe ser el responsable de liberarlo. Esta simple regla, conocida como RAII (Resource Acquisition Is Initialization), es una de las prácticas más importantes para escribir código en C++ seguro y profesional.
Gracias por leernos.
Si te gusto este artículo, únete a nuestra comunidad en Facebook o WhatsApp para más…
¡Hasta la próxima!



