Menu
Coddy logo textTech

Liste di inizializzazione dei costruttori

Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 22 di 104.

Hai già visto la sintassi con i due punti in lezioni precedenti, come Player(std::string n, int h) : name(n), health(h) {}. Si chiama lista di inizializzazione dei membri ed è il modo preferito per inizializzare i membri in C++.

L’elenco di inizializzazione compare dopo l’elenco dei parametri del costruttore, iniziando con due punti. Ogni membro viene inizializzato direttamente con il proprio valore, separato da virgole:

class Rectangle {
    int width;
    int height;
    const int id;
    int& reference;
public:
    Rectangle(int w, int h, int i, int& r) 
        : width(w), height(h), id(i), reference(r) {
        // Corpo del costruttore (può essere vuoto)
    }
};

Perché usare le liste di inizializzazione invece dell'assegnazione nel corpo del costruttore? Con l'assegnazione, i membri vengono prima costruiti con i valori predefiniti e poi ricevono i nuovi valori. Con le liste di inizializzazione, i membri vengono costruiti direttamente con i valori corretti: è più efficiente e talvolta necessario.

Alcuni membri devono essere inizializzati utilizzando la lista:

  • membri const - non possono essere assegnati dopo la costruzione
  • Membri di riferimento: devono essere associati durante l'inizializzazione
  • Membri senza costruttori predefiniti
class Player {
    const int maxHealth;    // È necessario usare la lista di inizializzazione
    std::string name;
public:
    // Questo funziona
    Player(int max, std::string n) : maxHealth(max), name(n) {}
    
    // Questo NON verrebbe compilato:
    // Player(int max) { maxHealth = max; }  // Errore!
};

I membri vengono inizializzati nell'ordine in cui sono dichiarati nella classe, non nell'ordine dell'elenco degli inizializzatori. Scrivi sempre l'elenco degli inizializzatori nell'ordine di dichiarazione per evitare confusione.

challenge icon

Sfida

Facile

Costruiamo un sistema di configurazione per un motore di gioco che dimostri quando e perché le liste di inizializzazione dei membri sono essenziali. Creerai una classe GameConfig con membri che MUST essere inizializzati usando la sintassi delle liste di inizializzazione.

Creerai due file per organizzare il codice:

  • GameConfig.h: definisci una classe GameConfig che memorizza le impostazioni del gioco. La classe deve avere:
    • Una const std::string gameName: il titolo del gioco, che non può essere modificato dopo la creazione
    • Una const int maxPlayers: il numero massimo di giocatori, fissato al momento della costruzione
    • Una int& difficultyRef: un riferimento a un'impostazione di difficoltà esterna
    • Un int screenWidth e un int screenHeight: membri normali per le impostazioni di visualizzazione
    • Un costruttore che accetta tutti i parametri necessari e inizializza EVERY membro usando la lista di inizializzazione. La lista di inizializzazione deve seguire l'ordine in cui i membri sono dichiarati nella classe
    • Un metodo display() che stampa la configurazione in questo formato:
      Game: <gameName>
      Max Players: <maxPlayers>
      Difficulty: <difficultyRef value>
      Resolution: <screenWidth>x<screenHeight>
  • main.cpp: leggi i valori di configurazione dall'input e crea un oggetto GameConfig. Dovrai:
    • Leggere dall'input il nome del gioco (string), il numero massimo di giocatori (int), la difficoltà (int), la larghezza (int) e l'altezza (int): ciascuno su una riga separata
    • Creare una variabile locale int per la difficoltà a cui farà riferimento la configurazione
    • Creare un oggetto GameConfig usando il costruttore con lista di inizializzazione
    • Chiamare display() per mostrare la configurazione iniziale
    • Modificare direttamente la variabile della difficoltà (moltiplicarla per 2)
    • Stampare "After difficulty change:"
    • Chiamare di nuovo display() per mostrare che il riferimento riflette il valore aggiornato

Questa sfida evidenzia perché le liste di inizializzazione sono importanti: i membri const e il membro riferimento non possono essere assegnati nel corpo del costruttore. Devono essere inizializzati nella lista. Il membro riferimento dimostra anche come le modifiche alla variabile originale si riflettano attraverso l'oggetto di configurazione.

Includi il file header in main.cpp usando #include "GameConfig.h".

Provalo tu

#include <iostream>
#include <string>
#include "GameConfig.h"

using namespace std;

int main() {
    // Leggi i valori di input
    string gameName;
    getline(cin, gameName);
    
    int maxPlayers;
    cin >> maxPlayers;
    
    int difficulty;
    cin >> difficulty;
    
    int width;
    cin >> width;
    
    int height;
    cin >> height;
    
    // TODO: Crea un oggetto GameConfig usando il costruttore con lista di inizializzazione
    // Il costruttore deve ricevere: gameName, maxPlayers, difficulty (per riferimento), width, height
    
    // TODO: Chiama display() per mostrare la configurazione iniziale
    
    // TODO: Modifica direttamente la variabile difficulty (moltiplicala per 2)
    
    // TODO: Stampa "After difficulty change:"
    
    // TODO: Chiama di nuovo display() per mostrare la configurazione aggiornata
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C++ online