Getter e setter
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 28 di 104.
Quando i membri di una classe sono privati, il codice esterno non può accedervi direttamente. I getter e i setter sono metodi pubblici che forniscono un accesso controllato a questi membri privati: i getter recuperano i valori, i setter li modificano.
class Temperature {
double celsius; // Privato - non è accessibile direttamente
public:
// Getter - restituisce il valore
double getCelsius() const {
return celsius;
}
// Setter - modifica il valore con una verifica di validità
void setCelsius(double value) {
if (value >= -273.15) { // Controllo dello zero assoluto
celsius = value;
}
}
};Il vero potere dei setter è la convalida.
Invece di consentire l’assegnazione di qualsiasi valore, puoi imporre delle regole. Nell’esempio precedente, le temperature inferiori allo zero assoluto vengono rifiutate. Senza un setter, chiunque potrebbe assegnare direttamente dati non validi.
I getter possono anche trasformare i dati prima di restituirli:
class Temperature {
double celsius;
public:
double getCelsius() const { return celsius; }
// Getter calcolato - non memorizza fahrenheit, lo calcola
double getFahrenheit() const {
return celsius * 9.0 / 5.0 + 32.0;
}
void setCelsius(double value) { celsius = value; }
};Nota la parola chiave const nei getter: indica che non modificano l’oggetto. I setter non possono essere const, poiché il loro scopo è modificare i valori dei membri. Questo schema di utilizzo di getter e setter è fondamentale per l’incapsulamento e ti offre il pieno controllo su come i dati della tua classe vengono consultati e modificati.
Sfida
FacileCostruiamo un sistema di profili dei giocatori che dimostri come getter e setter offrano un accesso controllato ai dati privati, includendo la convalida e le proprietà calcolate.
Creerai due file per organizzare il codice:
Player.h: definisci una classePlayerche gestisce il profilo di un personaggio di gioco con accesso protetto ai dati. La tua classe dovrebbe avere:- Membri privati:
name(stringa),level(int) eexperience(int) - Un costruttore che accetta un nome e inizializza
levela1eexperiencea0 - Un getter
getName()che restituisce il nome del giocatore - Un getter
getLevel()che restituisce il livello attuale - Un getter
getExperience()che restituisce i punti esperienza attuali - Un setter
setName()che accetta solo nomi di almeno 3 caratteri; se il nome non è valido, mantieni invariato quello attuale - Un setter
addExperience(int points)che accetta solo valori positivi. Quando l'esperienza raggiunge o supera100, il giocatore sale di livello: incrementa il livello di 1 e sottrai 100 dall'esperienza. Questo può accadere più volte se vengono aggiunti abbastanza punti esperienza. - Un getter calcolato
getExperienceToNextLevel()che restituisce quanti altri punti esperienza servono per raggiungere il livello successivo (sempre100 - current experience)
Contrassegna tutti i getter come
const, poiché non modificano l'oggetto.- Membri privati:
main.cpp: mostra i getter e i setter in azione. Leggi da input il nome di un giocatore e i punti esperienza da aggiungere (ciascuno su una riga separata), poi:- Crea un
Playercon il nome inserito - Stampa
"Player: <name>, Level: <level>, XP: <experience>" - Aggiungi i punti esperienza inseriti usando
addExperience() - Stampa di nuovo la stessa riga di stato per mostrare lo stato aggiornato
- Stampa
"XP to next level: <amount>" - Prova a cambiare il nome in
"Al"(la convalida dovrebbe fallire) - Stampa
"Name after invalid change: <name>" - Cambia il nome in
"Champion"(la convalida dovrebbe avere esito positivo) - Stampa
"Name after valid change: <name>"
- Crea un
L'esperienza verrà fornita come stringa, che dovrai convertire in un numero intero. Includi il file header nel file main.cpp usando #include "Player.h".
Provalo tu
#include <iostream>
#include <string>
#include "Player.h"
using namespace std;
int main() {
// Leggi il nome del giocatore
string playerName;
getline(cin, playerName);
// Leggi i punti esperienza da aggiungere (come string, poi converti in int)
string expString;
getline(cin, expString);
int expToAdd = stoi(expString);
// TODO: Crea un Player con il nome inserito
// TODO: Stampa lo stato iniziale: "Player: <name>, Level: <level>, XP: <experience>"
// TODO: Aggiungi i punti esperienza inseriti usando addExperience()
// TODO: Stampa la riga di stato aggiornata
// TODO: Stampa "XP to next level: <amount>"
// TODO: Prova a cambiare il nome in "Al" (la convalida dovrebbe fallire)
// TODO: Stampa "Name after invalid change: <name>"
// TODO: Cambia il nome in "Champion" (la convalida dovrebbe riuscire)
// TODO: Stampa "Name after valid change: <name>"
return 0;
}
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
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online