Incapsulamento, Classi e Metodi
Le classi “POD” (struct pure di soli dati) sono utili per creare agglomerati di variabili. Tuttavia, progettare software su larga scala usando solo dati nudi genera caos e dipendenze ovunque.
Il C++ offre il paradigma dell’Incapsulamento (Encapsulation): un pattern architetturale che collega indissolubilmente i dati con le funzioni che li manipolano. Questo migliora il codice in due modi:
- Raggruppa i concetti. Non hai più dati separati dalle funzioni; l’oggetto modella sia il suo stato che come esso varia.
- Permette l’Occultamento delle Informazioni (Information Hiding). Puoi impedire ad altro codice di manipolare i dati grezzi interni, forzandolo a passare tramite regole precise.
I Metodi (Member Functions)
Section titled “I Metodi (Member Functions)”I metodi non sono altro che funzioni definite all’interno del corpo di una classe (o struct). Poiché vivono dentro l’oggetto, i metodi possiedono un accesso speciale e automatico a tutti i membri dati dell’oggetto stesso.
struct Orologio { int anno;
// Questo è un metodo! void aggiungi_anno() { anno = anno + 1; // Accede direttamente alla variabile 'anno' }};Per chiamare il metodo su un’istanza dell’oggetto si utilizza sempre l’operatore punto (.):
Orologio mio_orologio;mio_orologio.anno = 2026;mio_orologio.aggiungi_anno(); // Ora l'anno è 2027Controlli di Accesso: public vs private
Section titled “Controlli di Accesso: public vs private”L’Occultamento delle Informazioni (Information Hiding) si attua tramite i controlli di accesso. In C++ ce ne sono due fondamentali:
public: Qualsiasi parte del programma può leggere o modificare liberamente il membro. (Nellestruct, tutti i membri sonopublicdi default).private: Il membro è totalmente inaccessibile dall’esterno. Può essere letto o manipolato esclusivamente dai metodi interni della classe stessa.
Immaginiamo di voler impedire che l’anno dell’orologio possa mai essere impostato a un valore inferiore al 2019. Se la variabile anno è pubblica, chiunque potrebbe scrivere mio_orologio.anno = 1990; corrompendo la logica di business.
Rendiamola privata e creiamo dei Setter e Getter:
struct OrologioSicuro { void aggiungi_anno() { anno++; }
// Metodo Setter con validazione dei dati bool set_anno(int nuovo_anno) { if (nuovo_anno < 2019) { return false; // Rifiuta la modifica! } anno = nuovo_anno; return true; }
// Metodo Getter per leggere il valore senza poterlo forzare int get_anno() { return anno; }
private: // Questa variabile non può più essere toccata dall'esterno! int anno;};La Parola Chiave class
Section titled “La Parola Chiave class”In C++, la parola chiave class funziona in modo pressoché identico a struct.
L’unica, cruciale, differenza tecnica tra le due è il livello di accesso predefinito:
- In una
struct, tutto ciò che dichiari èpublicdi default. - In una
class, tutto ciò che dichiari èprivatedi default, a meno che tu non scriva esplicitamentepublic:.
Dichiarare OrologioSicuro usando class apparirebbe così:
class OrologioSicuro { int anno; // E' private di default!
public: // Tutto ciò che segue sarà esposto all'esterno void aggiungi_anno() { ... } bool set_anno(int nuovo_anno) { ... } int get_anno() { ... }};La scelta tra class o struct è puramente stilistica. Molte guide stilistiche aziendali usano struct esclusivamente per i POD (dati nudi senza metodi complessi) e class per i tipi completamente incapsulati.
Esercizio Pratico: Il Guardiano del Tempo
Section titled “Esercizio Pratico: Il Guardiano del Tempo”Completa la classe OrologioSicuro. Implementa la logica del metodo set_anno affinché scarti i valori inferiori a 2019 e aggiorni il valore in caso contrario.