Riguardando 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.
Lascia un commento