Menu
Coddy logo textTech

Specificatori di accesso in dettaglio

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

Ora che hai compreso i tre specificatori di accesso, scopriamo come si comportano quando hai più oggetti della stessa classe. Un malinteso comune è che private significhi «solo questo oggetto», ma in realtà significa «solo questa classe».

Gli oggetti della stessa classe possono accedere ai membri privati degli altri:

class Person {
    std::string secret;
    
public:
    Person(std::string s) : secret(s) {}
    
    void readSecret(const Person& other) {
        // Accesso al membro privato di un altro oggetto - consentito!
        std::cout << other.secret;
    }
};

Questo funziona perché il controllo degli accessi viene applicato a livello di classe, non a livello di oggetto. Il metodo readSecret fa parte della classe Person, quindi può accedere ai membri privati di qualsiasi oggetto Person. Questa progettazione consente a operazioni come i costruttori di copia e gli operatori di confronto di lavorare con lo stato interno di altri oggetti.

Puoi anche passare da uno specificatore di accesso all'altro più volte all'interno di una classe:

class Mixed {
public:
    void publicMethod1();
    
private:
    int privateData;
    
public:
    void publicMethod2();    // Di nuovo public
    
private:
    void privateHelper();    // Di nuovo private
};

Sebbene questo sia C++ valido, in genere è meglio raggruppare i membri in base al livello di accesso per migliorare la leggibilità. La maggior parte delle guide di stile consiglia di elencare prima i membri pubblici (poiché costituiscono l’interfaccia della classe), poi quelli protetti e infine quelli privati.

challenge icon

Sfida

Facile

Costruiamo un sistema di confronto tra portafogli che mostri come oggetti della stessa classe possano accedere ai membri privati degli altri oggetti. Questo è un aspetto fondamentale del controllo degli accessi in C++: viene applicato a livello di classe, non di oggetto.

Creerai due file per organizzare il codice:

  • Wallet.h: definisci una classe Wallet che memorizza dati finanziari privati, ma consente confronti tra portafogli. La classe dovrebbe avere:
    • Membri privati: ownerName (stringa) e balance (double)
    • Un costruttore che accetta il nome del proprietario e il saldo iniziale
    • Un getter pubblico getOwnerName() che restituisce il nome del proprietario
    • Un metodo hasMoreThan(const Wallet& other) che confronta il saldo di questo portafoglio con il saldo privato di un altro portafoglio e restituisce true se questo portafoglio ha più denaro
    • Un metodo combinedBalance(const Wallet& other) che restituisce la somma dei saldi privati di entrambi i portafogli
    • Un metodo transferTo(Wallet& other, double amount) che trasferisce denaro da questo portafoglio a un altro. Dovrebbe modificare direttamente i saldi privati di entrambi i portafogli (solo se l'importo è positivo e non supera il saldo di questo portafoglio)
  • main.cpp: mostra l'accesso ai membri privati di un altro oggetto. Leggi dall'input due nomi di proprietari e due saldi (quattro righe: name1, balance1, name2, balance2), poi:
    • Crea due oggetti Wallet con i valori inseriti
    • Stampa "Combined wealth: $<amount>" usando combinedBalance()
    • Confronta i portafogli e stampa "<name> has more money" per il proprietario con il saldo più alto (usa hasMoreThan() per stabilirlo)
    • Trasferisci 100.0 dal primo portafoglio al secondo usando transferTo()
    • Stampa "After transfer:"
    • Stampa di nuovo "Combined wealth: $<amount>" (dovrebbe rimanere invariato)
    • Confronta di nuovo e stampa "<name> has more money" (il risultato potrebbe essere cambiato)

Il concetto chiave è che metodi come hasMoreThan() e transferTo() possono accedere direttamente al membro privato balance di un altro oggetto Wallet: non servono getter. Questo è possibile perché il controllo degli accessi in C++ è basato sulla classe: qualsiasi codice all'interno della classe Wallet può accedere ai membri privati di qualsiasi oggetto Wallet.

Formatta tutti gli importi con due cifre decimali usando std::fixed e std::setprecision(2) da <iomanip>. Converti i valori dei saldi in input usando std::stod().

Provalo tu

#include <iostream>
#include <string>
#include <iomanip>
#include "Wallet.h"

using namespace std;

int main() {
    // Leggi l'input: name1, balance1, name2, balance2
    string name1, name2;
    string balanceStr1, balanceStr2;
    
    getline(cin, name1);
    getline(cin, balanceStr1);
    getline(cin, name2);
    getline(cin, balanceStr2);
    
    double balance1 = stod(balanceStr1);
    double balance2 = stod(balanceStr2);
    
    // Imposta il formato di output per i valori monetari
    cout << fixed << setprecision(2);
    
    // TODO: Crea due oggetti Wallet con i valori di input
    
    // TODO: Stampa il patrimonio complessivo usando combinedBalance()
    // Formato: "Combined wealth: $<amount>"
    
    // TODO: Confronta i portafogli usando hasMoreThan() e stampa chi ha più denaro
    // Formato: "<name> has more money"
    
    // TODO: Trasferisci 100.0 dal primo portafoglio al secondo usando transferTo()
    
    // TODO: Stampa "After transfer:"
    
    // TODO: Stampa di nuovo il patrimonio complessivo
    
    // TODO: Confronta di nuovo i portafogli e stampa chi ha più denaro
    
    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