Specificatori di accesso in C++
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 34 di 104.
C++ fornisce tre specificatori di accesso che controllano chi può accedere ai membri di una classe: public, protected e private. Questi costituiscono le basi dell'incapsulamento.
class Account {
public:
std::string ownerName; // Accessibile da qualsiasi punto
protected:
double interestRate; // Accessibile in questa classe e nelle classi derivate
private:
double balance; // Accessibile solo all'interno di questa classe
};I membri public sono accessibili da qualsiasi punto: all'interno della classe, dalle classi derivate e dal codice esterno. I membri private sono i più restrittivi, accessibili solo all'interno della classe stessa. Protected si colloca a metà: si comporta come private per il mondo esterno, ma le classi derivate possono accedere a questi membri.
class Account {
private:
double balance;
public:
Account() : balance(0) {}
void deposit(double amount) {
balance += amount; // OK - all'interno della classe
}
};
int main() {
Account acc;
acc.deposit(100); // OK - deposit è pubblico
// acc.balance = 500; // ERROR - balance è privato
}Per impostazione predefinita, tutti i membri di una classe sono privati se non viene specificato alcun modificatore. Questo ti incoraggia a decidere esplicitamente cosa rendere accessibile. In genere, i membri dati vengono resi privati e si forniscono metodi pubblici per interagire con essi in modo sicuro.
Sfida
FacileCostruiamo un semplice sistema di gestione dei dipendenti che dimostri come gli specificatori di accesso controllano chi può accedere a cosa. Creerai una classe in cui alcuni dati sono completamente privati, alcuni sono accessibili alle potenziali sottoclassi e altri sono aperti a tutti.
Creerai due file per organizzare il codice:
Employee.h: definisci una classeEmployeeche utilizza tutti e tre gli specificatori di accesso per proteggere i dati in modo appropriato:- Pubblico: il
namedel dipendente (stringa). È accessibile da qualsiasi punto - Protetto: il
departmentdel dipendente (stringa): accessibile all'interno della classe e dalle classi derivate, ma non dall'esterno - Privato: il
salarydel dipendente (double): accessibile solo all'interno della classe stessa - Un costruttore che accetta name, department e salary per inizializzare tutti e tre i membri
- Un metodo pubblico
getSalary()che restituisce il valore privato salary - Un metodo pubblico
getDepartment()che restituisce il valore protetto department - Un metodo pubblico
giveRaise(double amount)che aumenta salary dell'importo specificato (solo se amount è positivo) - Un metodo pubblico
displayInfo()che stampa le informazioni del dipendente nel formato:"Name: <name>, Department: <department>, Salary: $<salary>"
- Pubblico: il
main.cpp: dimostra come funzionano gli specificatori di accesso interagendo con un oggetto Employee. Leggi da input il nome, il reparto e lo stipendio di un dipendente (tre righe separate), poi:- Crea un
Employeecon i valori di input - Stampa direttamente il nome del dipendente accedendo al membro pubblico:
"Direct access - Name: <name>" - Stampa il reparto usando il getter:
"Via getter - Department: <department>" - Stampa lo stipendio usando il getter:
"Via getter - Salary: $<salary>" - Concedi al dipendente un aumento di
5000.0 - Stampa
"After raise:" - Chiama
displayInfo()per mostrare le informazioni aggiornate
- Crea un
Formatta tutti i valori dello stipendio con due cifre decimali usando std::fixed e std::setprecision(2) da <iomanip>. Converti l'input dello stipendio da stringa a double usando std::stod().
Il punto fondamentale è che, mentre puoi accedere direttamente a name da main, non puoi accedere direttamente a department o salary. Devi usare i metodi getter pubblici. Questa è l'incapsulamento in azione: la classe controlla come si accede ai suoi dati e come vengono modificati.
Provalo tu
#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"
using namespace std;
int main() {
// Leggi l'input
string name;
string department;
string salaryStr;
getline(cin, name);
getline(cin, department);
getline(cin, salaryStr);
double salary = stod(salaryStr);
// Imposta la precisione per la visualizzazione dello stipendio
cout << fixed << setprecision(2);
// TODO: Crea un oggetto Employee con i valori di input
// TODO: Stampa il nome del dipendente accedendo direttamente al membro pubblico
// Formato: "Direct access - Name: <name>"
// TODO: Stampa il reparto usando il metodo getter
// Formato: "Via getter - Department: <department>"
// TODO: Stampa lo stipendio usando il metodo getter
// Formato: "Via getter - Salary: $<salary>"
// TODO: Concedi al dipendente un aumento di 5000.0
// TODO: Stampa "After raise:"
// TODO: Chiama displayInfo() per mostrare le informazioni aggiornate
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