Quando viene programmato un gioco, il codice è
pieno di funzioni e classi, le quali possono diventare ingestibili in
un singolo file. Inoltre è utile riutilizzare parte dei propri
programmi, ad esempio alcune classi e funzioni, come base per
successivi programmi in C++. Bisogna quindi spezzare il codice in
pezzi maneggevoli e utili attraverso file multipli. Generalmente si
separano le funzioni relative o le singole classi in un file proprio.
Il programma Roditore
Il programma Roditore non è composto da un solo
file, è una collezione di tre files che lavorano insieme per creare
una singola applicazione. Si tratta di un progetto molto semplice.
Viene instanziato un solo roditore, il quale dice “ciao”. Questo
esempio dimostra come sia possibile spezzare il programma in file
multipli.
Usare un file
E' possibile creare questo semplice programma con un
singolo file di codice, in quanto piuttosto corto, come mostrato
sotto.
#include<iostream>
using namespace std;
class Roditore
{ public: void Saluto();
};
void Roditore::Saluto()
{ cout << “Ciao, Io
sono un roditore.\n”; }
int main()
{ cout << “Creare un
oggetto Roditore.\n”;
Roditore ctopo;
ctopo.Saluto();
return 0;
}
Comunque, è possibile spezzare questo file in file
multipli che lavorano assieme come un progetto, come viene fatto di
seguito. In questo progetto sono creati 3 files.
- File intestazione. Contiene solo la definizione della classe Roditore.
- File implementazione. Contiene l'implementazione delle funzioni membro della classe Roditore.
- File applicazione. Contiene il programma, con la funzione main(), la quale usa la classe Roditore presente nei file implementazione e intestazione. Questo file viene eseguito dal compilatore.
Creare un file intestazione (Header)
I file
header sono creati per
essere inclusi in altri file. Si è già parlato di file intestazione
in quanto ogni programma già presentato include almeno un file
header proveniente dalla
libreria standard, <iostream>.
Quando si spezza il programma in file multipli, generalmente si
scrive un proprio file intestazione e solitamente lo si fa per ogni
classe. Questo file include solo la definizione della classe, non la
sua implementazione.
//roditore.h
//file
intestazione
#ifndef
RODITORE_H
#define
RODITORE_H
class Roditore
{ public: void Saluto();
};
#endif
La definizione
della classe Roditore
è molto semplice, in quanto dichiara una sola funzione pubblica,
Saluto().
Vi sono alcuni concetti nuovi nel codice. Le tre linee che iniziano
per # sono direttive del
preprocessore, in
pratica istruzioni per il compilatore.
Insieme dicono al compilatore cosa non includere nella definizione di
Roditore del progetto se sono già state incluse in esso. Viene presa
questa precauzione per evitare che la stessa classe sia definita più
di una volta nel codice, questo risulta in un errore. Cosa sta
succedendo? La prima direttiva dice che se il simbolo RODITORE_H non
è stato definito (in una lista di simboli che il compilatore
conserva per compilare il codice), il programma deve andare avanti e
processare tutto il codice che segue, sino al marcatore della
terminazione.
#ifndef
RODITORE_H
Se il simbolo è sulla
lista, il programma deve saltare tutto il codice che segue, sino al
marcatore di terminazione. Il marcatore di fine è l'ultima direttiva
presente sul file.
#endif
La prima volta che roditore.h il file intestazione viene
incluso nel processo, esso viene compilato, RODITORE_H non è nella
lista dei simboli, e vien inclusa la definizione della classe
Roditore. Inoltre il compilatore processa la direttiva, la
quale chiede di includere il simbolo RODITORE_H nella sua lista di
simboli.
#define
RODITORE_H
Questo significa che se vien fatto un altro
tentativo di includere questo file intestazione nel progetto, il
compilatore dopo aver visto il simbolo RODITORE_H nella lista,
salterà la definizione della classe Roditore, senza tentare
di definirla un'altra volta. Comunque il simbolo RODITORE_H che viene
scelto per il file d'intestazione nasce da una convenzione, per la
quale il nome del file viene scritto in maiuscole seguite da _H.
Questa convenzione ci permette di definire un simbolo unico per ogni
file intestazione. Inoltre è quello che ogni altro programmatore si
aspetta di trovare scritto.
Creare il file implementazione
Poiché il file intestazione contiene solo la
definizione della classe, i dati di implementazione della classe
devono essere immagazzinati in un altro file. Questo file deve avere
lo stesso nome del file intestazione, ma la sua estensione è la
familiare .cpp. L'implementazione di roditore.h viene
chiamata roditore.cpp. Di seguito si riporta il codice.
//roditore.cpp
//file implementazione
#include<iostream>
#include “roditore.h”
using namespace std;
void Roditore::Saluto()
{ cout << “Ciao, Io
sono un roditore.\n”; }
Il file contiene l'implementazione di
Roditore::Saluto(). Inoltre include la definizione delle variabili e
dei membri statici. Da notare l'istruzione con la quale viene incluso
il file intestazione:
#include “roditore.h”
Quando si effettua un'inclusione, è come se una
copia venga incollata direttamente dove si trova l'istruzione
include. Includendo roditore.h si completa la
definizione della classe. Questi due file insieme rappresentano un
modo pulito per memorizzare una singola classe. Il passo successivo è
usare la classe in un programma reale.
Creare file applicazione
Si possono
includere i propri file intestazione nell'applicazione usando
l'istruzione include.
Viene incluso roditore.h
in una semplice applicazione. Di seguito viene riportato il codice.
//roditore_app.cpp
//file
applicazione
#include<iostream>
#include
“roditore.h”
using namespace std;
int main()
{ cout << “Creare un
oggetto Roditore.\n”;
Roditore ctopo;
ctopo.Saluto();
return 0;
}
Quando viene
compilato il programma, il compilatore legge la seguente linea di
codice e la definizione della classe Roditore
memorizzata nei file roditore.h
e roditore.cpp.
#include
“roditore.h”
Come se il codice
di definizione fosse stato aggiunto al programma. Pertanto durante
l'esecuzione, l'oggetto Roditore
viene fatta istanza e la funzione dice ciao.
Nessun commento:
Posta un commento