- Comprendere il ruolo del costruttore nel ciclo di vita di un oggetto
- Saper utilizzare i parametri del costruttore per inizializzare gli attributi
- Distinguere tra stato non inizializzato e stato coerente di un'istanza
- Implementare classi con metodi di controllo basati su dati iniziali certi
Dopo aver modellato oggetti statici, passiamo a un dispositivo che utilizziamo quotidianamente: lo Smartphone. In questa modellazione, il concetto chiave è la coerenza dei dati fin dal momento della nascita dell'oggetto.
Per evitare che un oggetto venga creato "vuoto" o con dati errati, utilizzeremo il Costruttore. Si tratta di un metodo speciale che:
- Viene eseguito una sola volta all'istanziazione.
- Prende i dati dall'esterno e li "incastra" negli attributi privati o pubblici.
| Attributo | Tipo | Descrizione |
|---|---|---|
| marca | string | Produttore del dispositivo. |
| modello | string | Nome commerciale del prodotto. |
| batteria | int | Percentuale di carica residua (0-100). |
Il Cuore della Classe: Il Costruttore
Nelle lezioni precedenti abbiamo visto come creare oggetti e assegnare valori ai loro attributi manualmente nel main. Questo approccio è però rischioso: potremmo dimenticare di inizializzare un dato importante, creando un oggetto "incompleto".
Il Costruttore è un metodo speciale che viene richiamato automaticamente nel momento esatto in cui l'oggetto viene creato (istanziato). Le sue regole d'oro sono:
- Deve avere lo stesso identico nome della classe.
- Non ha tipo di ritorno (nemmeno void).
- Serve principalmente a dare valori iniziali agli attributi.
Esempio
Un costruttore è un metodo speciale della classe che viene chiamato automaticamente quando si crea un oggetto. Serve a inizializzare gli attributi dell’oggetto.
class Studente {
public:
string nome;
string cognome;
int matricola;
float mediaVoti;
// Costruttore
Studente(string n, string c, int m, float media) {
nome = n;
cognome = c;
matricola = m;
mediaVoti = media;
}
void visualizzaDati() {
cout << "STUDENTE: " << nome << " " << cognome << endl;
cout << "Matricola: " << matricola << " | Media: " << mediaVoti << endl;
cout << "-----------------------------" << endl;
}
};
int main() {
// Creazione di oggetti utilizzando il costruttore
Studente s1("Mario", "Rossi", 12345, 7.5);
Studente s2("Luigi", "Bianchi", 56789, 8.2);
s1.visualizzaDati();
s2.visualizzaDati();
return 0;
}
Cosa cambia rispetto alla versione senza costruttore:
- Gli attributi sono inizializzati automaticamente alla creazione dell’oggetto.
- Non è necessario assegnare manualmente i valori dopo aver creato l’oggetto.
- Il codice è più pulito e meno soggetto a errori.
| Elemento | Sintassi C++ | Nota Didattica |
|---|---|---|
| Dichiarazione | NomeClasse(parametri) |
Sempre nella sezione public. |
| Assegnazione | this->attributo = valore; |
Collega i parametri della funzione ai dati della classe. |
| Chiamata | NomeClasse oggetto(valori); |
Avviene sulla stessa riga della creazione. |
LABORATORIO
Modellazione Smartphone con Inizializzazione
Obiettivo: Utilizzare il costruttore per garantire che ogni Smartphone creato abbia marca, modello e carica della batteria definiti subito.
- Dev-C++ o Code::Blocks
- Utilizzo di parametri formali e attuali
1 Esercitazione Guidata: La Classe Smartphone col Costruttore
Analizziamo come la sintassi del costruttore permetta di scrivere un main molto più pulito e sicuro.
Passo 1: Definizione della classe con il costruttore parametrizzato.
#include <iostream>
#include <string>
using namespace std;
class Smartphone {
public:
string marca;
string modello;
int batteria; // percentuale da 0 a 100
// COSTRUTTORE: nome uguale alla classe, nessun tipo di ritorno
Smartphone(string mrc, string mdl, int bat) {
marca = mrc;
modello = mdl;
batteria = bat;
cout << "[Sistema]: Nuovo smartphone creato: " << marca << " " << modello << endl;
}
void mostraStato() {
cout << "Dispositivo: " << marca << " " << modello << " | Carica: " << batteria << "%" << endl;
}
void usaApp() {
if (batteria > 5) {
batteria -= 5;
cout << "App utilizzata. Batteria residua: " << batteria << "%" << endl;
} else {
cout << "Batteria troppo scarica per avviare app!" << endl;
}
}
};
Passo 2: Istanziazione immediata degli oggetti nel main.
int main() {
// Creazione oggetti passandogli i dati DIRETTAMENTE tra parentesi
Smartphone tel1("Apple", "iPhone 15", 85);
Smartphone tel2("Samsung", "Galaxy S23", 10);
tel1.mostraStato();
tel2.mostraStato();
tel2.usaApp();
tel2.usaApp(); // Questo dovrebbe mostrare l'avviso di batteria scarica
return 0;
}
2 Esercizio: Ricarica SmartPhone
Modifica la classe Smartphone in modo che sia possibile Ricaricare lo Smartphone e riportare la batteria a 100.