Linguaggio C++

Il Distruttore

Ciclo di vita degli oggetti in C++: Costruttori, Distruttori. Scopri come gestire automaticamente la vita degli oggetti in C++ con costruttori e distruttori, evitando errori e garantendo codice sicuro e leggibile

Durata

20 minuti

Software

Dev-C++ o Visual Studio Code (MinGW)

Programmazione Ad Oggetti | Il Distruttore

In C++, ogni oggetto ha un ciclo di vita: nasce, viene utilizzato e poi viene eliminato. Per gestire automaticamente questa vita, esistono due strumenti fondamentali: costruttori e distruttori.

1. Il Costruttore (Constructor)

Un costruttore in C++ è una funzione speciale di una classe che viene chiamata automaticamente quando un oggetto viene creato. Serve principalmente a inizializzare i membri della classe, cioè a dare valori iniziali alle variabili dell’oggetto.

È un metodo speciale che ha lo stesso nome della classe e non ha tipo di ritorno (nemmeno void).

🔧 Caratteristiche fondamentali
  • Ha lo stesso nome della classe.
  • Se la classe si chiama Punto, il costruttore si chiamerà Punto.
  • Non ha tipo di ritorno, nemmeno void.
  • Viene chiamato automaticamente quando crei un oggetto.
  • Può essere sovraccaricato: puoi avere più costruttori con parametri diversi.
  • Se non ne definisci uno, il compilatore ne crea uno di default.
class Punto {
private:
    int x, y;

public:
    // Costruttore
    Punto(int a, int b) {
        x = a;
        y = b;
    }
};
Quando
Punto p(3, 4);
il costruttore viene chiamato automaticamente e imposta x = 3 e y = 4.

💡 Senza il costruttore, dovresti impostare manualmente x e y, rischiando errori e valori casuali.

✨ Perché è importante

I costruttori rendono il codice più sicuro e leggibile, perché garantiscono che ogni oggetto inizi la sua vita in uno stato coerente. Senza di loro, dovresti ricordarti ogni volta di inizializzare tutto manualmente.

In C++, l'Overloading del Costruttore è la tecnica che permette di definire più costruttori all'interno della stessa classe, ognuno con una lista di parametri differente.
Come funziona? Il compilatore distingue i vari costruttori in base alla loro firma (signature), ovvero il numero, il tipo e l'ordine dei parametri passati. Quando crei un oggetto, il compilatore "guarda" gli argomenti che stai fornendo e richiama il costruttore che combacia esattamente con quella sequenza.

2. Il Distruttore (Destructor)

Il distruttore è il “saluto finale” di un oggetto in C++: un metodo speciale che viene eseguito automaticamente quando l’oggetto sta per essere eliminato. Se il costruttore prepara l’oggetto alla vita, il distruttore si occupa di chiudere tutto in modo ordinato.

🗑️ Cos’è un distruttore
  • Ha lo stesso nome della classe, preceduto da una tilde ~ .
  • Non ha tipo di ritorno.
  • Non accetta parametri.
  • Serve a liberare risorse (memoria, file aperti, connessioni).
  • Viene chiamato in automatico quando l’oggetto esce di scope o viene distrutto.
“Se il costruttore inizializza l’oggetto, il distruttore fa l’opposto: si occupa di liberare le risorse quando l’oggetto non serve più.”

class Punto {
private:
    int x, y;

public:
    // Costruttore
    Punto(int a, int b) {
        x = a;
        y = b;
    }

    // Distruttore
    ~Punto() {
        // Qui potresti liberare risorse o stampare un messaggio
        // std::cout << "Oggetto Punto distrutto\n";
    }
};
In questa classe il distruttore non deve fare nulla, perché x e y sono semplici tipi primitivi che vengono gestiti automaticamente. Ma la struttura è quella giusta.
🧩 Esempio con risorsa da liberare
Immagina che Punto memorizzi le coordinate in un array allocato con new. In questo caso il distruttore diventa fondamentale per evitare memory leak.

class Punto {
private:
    int* coord; // memoria dinamica

public:
    // Costruttore
    Punto(int a, int b) {
        coord = new int[2]; // allocazione dinamica
        coord[0] = a;
        coord[1] = b;
    }

    // Distruttore
    ~Punto() {
        delete[] coord; // liberazione della memoria
    }
};

3. Ciclo di vita di un oggetto

Puoi pensare al ciclo così:

Creazione oggetto -> Costruttore -> Uso -> Fine scope -> Distruttore


LABORATORIO

Inizializzazione dati videogioco

In questo laboratorio creeremo una classe che gestisce i dati di un Videogioco, assicurandoci che ogni personaggio nasca con i parametri corretti.


1 Implementazione della Classe con Costruttori


#include <iostream>
#include <string>
using namespace std;

class Player {
private:
    string nome;
    int salute;

public:
    // 1. Costruttore di Default
    Player() {
        nome = "Ospite";
        salute = 100;
        cout << "[Sistema] Creato giocatore standard." << endl;
    }

    // 2. Costruttore con Parametri (Overloading)
    Player(string n, int s) {
        nome = n;
        salute = s;
        cout << "[Sistema] Creato giocatore personalizzato: " << nome << endl;
    }

    // 3. Distruttore
    ~Player() {
        cout << "[Sistema] Il giocatore " << nome << " ha lasciato la sessione." << endl;
    }

    void status() {
        cout << "Player: " << nome << " | Salute: " << salute << endl;
    }
};

2 Test del ciclo di vita nel Main


int main() {
    cout << "--- Inizio Sessione ---" << endl;

    // Richiama il costruttore di default
    Player p1; 
    p1.status();

    // Richiama il costruttore con parametri
    Player p2("Warrior_99", 150);
    p2.status();

    cout << "--- Fine Sessione ---" << endl;
    return 0; 
    // Qui vengono chiamati automaticamente i distruttori di p2 e p1 (ordine inverso)
}

3 Esercitazione autonoma: Gestione Veicoli

Crea una classe Automobile.

  • Attributi: marca, modello, litriCarburante.
  • Costruttore 1: Imposta "Generica", "Base", 10 litri.
  • Costruttore 2: Riceve marca e modello, imposta carburante a 20 litri.
  • Distruttore: Stampa "Automobile rottamata".
  • Nel main: Crea un oggetto per ogni costruttore e osserva l'ordine delle stampe.

4 Approfondimento

Cosa succede se dichiariamo un oggetto come puntatore (Player* p = new Player();)? Il distruttore verrà chiamato solo quando useremo esplicitamente il comando delete p;. Questo è il cuore della gestione della memoria manuale in C++.






C++, OOP, Costruttore, Distruttore, Overloading, Lifecycle,