Lezione 12 – Appunti sulle classi in C++

9bc1a68eb59b0d8e0ec1bff5a930a956ee6653eb8a6c27a8cb2e8232d079a9c4Riguardando le varie lezioni di C++ ho notato che avevo dato per scontata una delle nozioni piรน importanti, ovvero la classe, a cui comunque avevo accennato nella precedente lezione ma nel solo contesto relativo alle basi di design grafico.

Una classe รจ uno strumento che da al programmatore la possibilitร  diย definireย nuovi type in piรน, come nel caso del design grafico, vi sono le classi derivate che invece permettono di organizzare templates e classi derivate che permettono al programmatore di usufruire delle loro relazioni.

La classe รจ un’entitร  astratta che si concretizza nel type. Per esempio, se sto programmando un videogame fantasy utilizzerรฒ un type comeย Spellย (Incantesimo).ย Ovviamente, nella scelta dei type si tenterร  di creare dei comandi che siano in grado di rimandare ai concetti voluti rendendo piรน semplice sia la comprensione sia la modifica eventuale del programma.

Nella pratica il momento in cui un programmatore scrive una classe crea delle parti che andranno aggiunte all’interfaccia. Immaginiamoci, un programma complicato come puรฒ essere un videogioco, dove vogliamo creare un piccolo calendario che l’utente possa osservare: tutti i dati che ci servono non verranno inseriti nella stessa pagina ma, per comoditร , verranno creati dei piani di lavoro. La classe si inserisce sul primo livello di lavoro, quello piรน basilare e, per questo, il nostro codice verrร  salvato in una cartella chiamata, per esempio, interfaccia come file header ovvero .h. Questo, infatti, verrร  poi utilizzato nel nostro codice di programmazione .cpp richiamandolo con un bel #include piazzato subito dopo il classico #include “iostream”.

Per applicare il concettoย e definire la rappresentazione di unย Date ed una serie di funzioni per manipolare le variabili possiamo usare una struttura (struct). Per esempio, osserviamo la costruzione del date prendendo l’esempio dal libro di Bjarne Stroustrup,ย Programming language.

struct Date {        //rappresentazione
       int d, m, y;

void init (int dd, int mm, int yy);   //inizializza d
void add_year (int n);    //aggiungi n anni a d
void add_month (int n);   //aggiungi n mesi a d
void add_day (int n);     //aggiungi n giorni a d
};

Ilย typeย voidย รจ un pointer che indica una memoriaย che viene, di norma, impiegato quando vogliamo trasmettere un address tra pezzi di codice che non conoscono il type lโ€™uno dellโ€™altro.

Lo stesso comandoย struct รจ per definizione una classe i cui membri sono predefiniti come pubblici, le funzioni ad esso connesse sono i suoiย membri e possono essere richamati solo per una specifica variabile di un dato type. Diverse strutture, quindi, possono avere diversi membri con lo stesso nome, ecco perchรฉ lo specifichiamo quando definiamo tali membri di funzione.

Possiamo, quindi, anche sostituireย struct Date { con il comandoย class Date {, questo ci permetterร  di specificare che le funzioni date sono le uniche che dipenderanno dalla rappresentazione di Date e le uniche che daranno diretto accesso agli oggetti della classe Date. Inoltre, nello spazio lasciato libero tra int d,m,y; e void init possiamo aggiungere public:ย il quale ha la funzione di separare il corpo della classe in due parti. La prima parte potrร  essere utilizzata solo dai membri della funzione mentre la seconda parte costituisce l’interfaccia pubblica degli oggetti della classe.

Probabilmente qualcuno si chiederร  cos’รจ la funzioneย init ( ): essa viene utilizzata per avere una funzione che imposti il valore di un oggetto e renda i data privati forzandoci ad inserirli ma, normalmente, si predilige l’uso di unย constructor il quale permette al programmatore di dichiarare una funzione che esplicitamente si proponga di inizializzare gli oggetti. Questi viene indicato con lo stesso nome della classe: sostituiremo, quindi, volendo init con Date.

Diamo un’occhiata ad alcune linee di comando (il codice รจ stato semplificato ma rende l’idea) per capire come scrivere, effettivamente, questo header.

//Header file .h
#ifndef DATE H        //include guard
#define DATE H
#include "iostream"
using namespace std;

class Date {
protected:
     date(const int& d, const int& m, const int& y);   //controlla la data e inizializza

public:
     Date(int d, int m, int y);    //anno, mese, giorno
     int day() const;   //valore non modificabile
     int month() const;
     int year() const;
     void set_day(const int& d);   //aggiungi giorno
     void set_month(const int& m); //aggiungi mese
     void set_year(const int& y);  //aggiungi giorno
};
#endif        //per #ifndef    

Nella prima sezione dedicata all’utilizzo delle librerie troviamoย #ifndef che viene denominataย Include guard oppureย macro guard;ย questa macro serve per evitare problemi di doppia inclusione (per chi non lo sapesse la doppia inclusione fa parte dell’insiemistica: dati gli insiemi A e B troviamo che A=Bโ‡”AโІBย e BโІA in cui il simboloย โІ significa incluso; quindi possiamo leggere il tutto in questo modo: “A รจ uguale a B se e solo se A รจ includo in B e B รจ incluso in A”). Facendo ciรฒ rendiamo il nostro file.hย indempotente ossia facciamo sรฌ che non vi siano effetti collaterali (ovvero delle modificazioni di valori) nelle funzioni. Ogni qualvolta usiamo l’include guard dobbiamo necessariamente ricordarci di chiudere alla fine dei nostri comandi conย #endif. Il codice tra #ifndef e #endif viene compilato solo se lo specifico identificatore รจ stato definito precedentemente: ecco perchรฉ troviamo nella seconda linea di comando delle librerieย #define. Ormai, conosciamo giร  da tempo sia iostream che using namespace std per cui non mi ci soffermerรฒ ma in caso di dubbi date un’occhiata qui.

Come giร  accennato class Date ci permette di specificare che le funzioni date sono le uniche a dipendereย da Date e, successivamente, troveremo la suddivisione tra la parte privata (protected) e quella pubblica (public) relativamente all’interfaccia. Nella prima parte inseriremo i valori della variabile int, ovvero d, m, yย (giorno-day, mese-month, anno-year) della classe Date.

Dopodichรฉ troviamo l’uso dell’operatore & che altro non รจ che dire “si riferisce a” mentre il comando set imposterร  la data. Mentreย void รจ unย return type di cui non ci interessa ilย risultato che la funzione restituisce.


Scopri di piรน da CODEXSPRAWL

Abbonati per ricevere gli ultimi articoli inviati alla tua e-mail.

Lascia un commento

Il tuo indirizzo email non sarร  pubblicato. I campi obbligatori sono contrassegnati *