Linguaggio C++

Modificatori Di Accesso

Public e Private in C++: controllare l’accesso ai dati negli oggetti.

Durata

50 minuti

Software

Compilatore C++, IDE (Code::Blocks, VS Code o Dev-C++)

Nella programmazione orientata agli oggetti (OOP), uno dei concetti fondamentali è l’incapsulamento, ovvero la capacità di nascondere i dettagli interni di una classe e di esporre solo ciò che è necessario all’esterno. In C++, questo principio viene realizzato tramite i modificatori di accesso (o access specifiers), che permettono di controllare la visibilità e l’accessibilità dei membri di una classe, come variabili e metodi.

I principali modificatori di accesso in C++ sono public, private e protected. Essi stabiliscono da quali parti del programma è possibile accedere ai membri di una classe: dall’interno della classe stessa, dalle classi derivate o dal codice esterno. L’uso corretto dei modificatori di accesso consente di scrivere codice più sicuro, modulare e facile da mantenere, riducendo il rischio di modifiche indesiderate allo stato interno degli oggetti.

Comprendere il funzionamento dei modificatori di accesso è quindi essenziale per progettare classi ben strutturate e per sfruttare appieno i principi della programmazione orientata agli oggetti in C++.

Cosa significa davvero "Accedere" a un dato?

In programmazione, accedere significa due cose molto semplici:

  • Leggere: Vedere cosa c'è scritto in una variabile (es. cout << oggetto.prezzo;).
  • Scrivere: Cambiare il valore di una variabile (es. oggetto.prezzo = 10;).
Quando diciamo che un modificatore "permette o nega l'accesso", stiamo decidendo se un'altra parte del programma può fare queste due operazioni.

Chi è che "Accede"?

Immaginiamo che il nostro programma sia diviso in due zone:

  • 1. "Dentro la Classe" (I Metodi): Immagina di essere dentro il codice della classe stessa. Qui sei "a casa tua". Hai le chiavi di tutte le stanze.
    Cosa puoi fare: Puoi toccare tutto. Le variabili private, public e protected sono tutte a tua disposizione.
  • 2. "Fuori dalla Classe" (Il mondo esterno / Il main): Immagina di essere nel main o in un'altra funzione esterna. Qui sei un ospite (o un utente).
    Cosa puoi fare: Puoi toccare solo ciò che è stato lasciato "in giardino" o "all'ingresso", ovvero ciò che è public. Non puoi entrare nelle stanze private.
Un esempio di codice per capire il "Chi".

Proviamo a vedere chi riesce a toccare la variabile temperatura in questo scenario:


class Caldaia {
    private:
        int temperatura; // Questa è privata!

    public:
        void imposta(int t) { 
            // QUI SIAMO "DENTRO": l'accesso è permesso.
            temperatura = t; 
        }
};

int main() {
    Caldaia miaCaldaia;

    // CHI ACCEDE QUI? Il main (mondo esterno).
    
    // miaCaldaia.temperatura = 80; 
    // ERRORE! Il main è "fuori" e prova a toccare un dato "private".
    
    miaCaldaia.imposta(80); 
    // FUNZIONA! Il main usa un metodo public (il pulsante) 
    // che a sua volta ha il permesso di toccare la variabile interna.
}
  • Se metti public, stai dicendo al main: "Prendi pure questa variabile, fai quello che vuoi".
  • Se metti private, stai dicendo al main: "Tu non puoi toccare questo dato. Se vuoi modificarlo, devi chiedere a me usando le mie funzioni pubbliche".

Esempio: Il profilo Social (Gestione Password)

Qui vediamo come il modificatore private protegga un dato che non deve mai essere letto dall'esterno, nemmeno per sbaglio.


class ProfiloSocial {
    private:
        string password; // Nessuno da fuori deve poter leggere la password

    public:
        string nomeUtente; // Il nome è pubblico, tutti possono vederlo

        ProfiloSocial(string user, string pass) {
            nomeUtente = user;
            password = pass;
        }

        // Metodo per cambiare password in sicurezza
        void cambiaPassword(string vecchia, string nuova) {
            if (vecchia == password) {
                password = nuova;
                cout << "Password aggiornata con successo!" << endl;
            } else {
                cout << "Vecchia password errata. Accesso negato." << endl;
            }
        }
};

int main() {
    ProfiloSocial mioProfilo("MarioRossi99", "12345");

    // ACCESSO AL NOME (Public)
    cout << "Utente: " << mioProfilo.nomeUtente << endl; // FUNZIONA

    // ACCESSO ALLA PASSWORD (Private)
    // cout << mioProfilo.password; 
    // ERRORE: Sarebbe un grave rischio di sicurezza se il main potesse leggere il dato private!

    mioProfilo.cambiaPassword("12345", "nuova_pass_sicura"); // FUNZIONA
}

LABORATORIO

Sistema di Controllo Drone

Obiettivo: Modellare un drone professionale dove l'altitudine e il seriale sono protetti da modifiche esterne non autorizzate, garantendo la sicurezza del volo.


1 Progettazione della Classe

Definiamo i dati sensibili in private. L'altitudine non può essere cambiata dal pilota scrivendo un numero nel main, ma solo chiamando il metodo decolla().


#include <iostream>
#include <string>
using namespace std;

class Drone {
    private:
        // DATI PROTETTI: Il main non può vederli né cambiarli
        string seriale;
        int altitudine;
        bool motoriAttivi;

    public:
        // Costruttore: Inizializza il drone a terra
        Drone(string s) {
            seriale = s;
            altitudine = 0;
            motoriAttivi = false;
        }

        // AZIONI PUBBLICHE: I pulsanti del radiocomando
        void avviaMotori() {
            motoriAttivi = true;
            cout << "Motori avviati correttamente." << endl;
        }

        void decolla() {
            if (motoriAttivi) {
                altitudine = 5; // Solo la classe può cambiare l'altitudine
                cout << "Decollo completato. Quota: 5 metri." << endl;
            } else {
                cout << "ERRORE: Impossibile decollare con motori spenti!" << endl;
            }
        }

        void stampaStato() {
            cout << "--- STATUS DRONE ---" << endl;
            cout << "S/N: " << seriale << endl;
            cout << "Altitudine: " << altitudine << "m" << endl;
            cout << "Motori: " << (motoriAttivi ? "ON" : "OFF") << endl;
        }
};

2 Test nel Main: Verifica dei Permessi

Implementiamo il test. Provate a forzare l'altitudine dal main per vedere come reagisce il compilatore.


int main() {
    Drone mioDrone("DRONE-A1");

    // OPERAZIONI CONSENTITE (Public)
    mioDrone.stampaStato();
    mioDrone.avviaMotori();
    mioDrone.decolla();
    mioDrone.stampaStato();

    // OPERAZIONI NEGATE (Private) - Togli il commento per testare l'errore
    // mioDrone.altitudine = 100; 
    // mioDrone.seriale = "HACKED";

    return 0;
}

3 Perché è importante?

Riflettiamo sul "chi" accede:

  • Il Seriale è privato: garantisce che l'identità del drone non venga manomessa dopo l'accensione.
  • L'Altitudine è privata: evita che un programmatore distratto porti il drone a 1000 metri istantaneamente dal main, causandone lo schianto. Il valore cambia solo tramite logica sicura (decolla).

4 Esercitazione Autonoma: Sicurezza Avanzata

Espandi il codice aggiungendo queste funzionalità:

  • Atterraggio: Aggiungi un metodo pubblico atterra() che porti l'altitudine a 0 e spenga i motori, ma solo se l'altitudine attuale è maggiore di zero.
  • Livello Batteria: Aggiungi un attributo batteria (int). Il metodo decolla() deve funzionare solo se la batteria è superiore al 20%.
  • Controllo Manuale: Crea un metodo setQuota(int q). Deve permettere di cambiare l'altitudine solo se il valore q è compreso tra 0 e 50 metri. Se il valore è fuori range, stampa un avviso di sicurezza.





C++, OOP, Public, Private, Incapsulamento, Informatica,