Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Scienze Matematiche Fisiche e Naturali
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Ernesto Burattini » 3.Programmazione a oggetti


Terminologia della programmazione a oggetti

Introduciamo alcuni termini che si usano nella programmazione a oggetti.

Esempi di oggetti sono le persone, gli animali, le piante, le automobili, gli aerei, i palazzi, i calcolatori e quant’altro.

Gli uomini pensano in termini di oggetti.

Possiamo suddividere gli oggetti in due grandi categorie: oggetti animati e inanimati. I primi si muovono e intraprendono azioni, al contrario dei secondi.
Entrambi i tipi di oggetti hanno una caratteristica in comune:
gli attributi, come ad esempio la dimensione, la forma, il colore, il peso, e così via.

Terminologia della programmazione a oggetti (segue)

Gli oggetti hanno tutti dei comportamenti: un pallone rotola, rimbalza, si gonfia o si sgonfia; un bambino piange, dorme, mangia, cammina; un’automobile accelera, frena, svolta; un asciugamano assorbe l’acqua e così via.

Nella programmazione a oggetti si devono individuare i tipi di attributi e i comportamenti che caratterizzano gli oggetti software individuati.

Un accenno alla programmazione a oggetti

In C l’unità di programmazione è la funzione.

In C++ l’unità è la classe, da cui eventualmente si istanziano (creano) gli oggetti.

La relazione fra classi e oggetti può essere esemplificata nel modo seguente:
il progetto di un’auto sta all’automobile allo stesso modo in cui la classe sta ad un oggetto.

Infatti, è possibile costruire parecchie automobili partendo dallo stesso progetto e, allo stesso modo, possiamo istanziare parecchi oggetti da una sola classe.

Non si può correre, frenare o girare con l’auto di un progetto: si può solo correre, frenare o girare con un’auto vera.

Un accenno alla programmazione a oggetti (segue)

Le strutture, utilizzabili con la parola chiave struct, hanno permesso di definire vari tipi, come studente, anagrafe, data etc., che si servono sia di tipi elementari che di altre strutture.

Così come accade per i tipi int e float, sarebbe auspicabile poter definire delle operazioni anche per strutture tipo la struct studente.

In questo caso, per esempio, potremmo avere, come operazioni la lettura e scrittura dei dati dello studente, il calcolo della media dei voti e delle tasse pagate fino ad un certo periodo, e così via.

È, quindi, evidente che è necessario introdurre un nuovo costrutto che inglobi in sè sia i dati che le operazioni.

A tal fine si introduce un nuovo tipo utilizzando la parola chiave class.

La nozione di classe e oggetti

Tipo: l’insieme dei valori che può assumere una variabile (semplice o strutturata) e l’insieme delle operazioni che possono applicarsi a tali valori.

Classe: la definizione di un tipo esteso che racchiude sia i valori che lo caratterizzano (proprietà), sia gli operatori che agiscono su quei valori (metodi).


Vantaggi delle classi

Incapsulamento dati:

  • I metodi come unico punto di accesso (interfaccia) alle sue proprietà;
  • Lo stato di un oggetto (l’insieme delle sue proprietà) può essere modificato solo attraverso l’interfaccia progettata (Oscuramento/Protezione dati).

Gli oggetti stream

Uno stream è un’astrazione, che rappresenta un “qualcosa” da o verso cui “fluisce” una sequenza di bytes.

Può essere interpretato come un “file intelligente” (con proprietà e metodi), che agisce come “sorgente” da cui estrarre (input), o “destinazione” in cui inserire (output) i dati.

Esempi di stream:

  • Input da tastiera, output a schermo;
  • File in lettura, file in scrittura;
  • Buffer;
  • Canali di trasmissione di rete.

Gli oggetti stream (segue)

Un concetto importante è la posizione corrente in uno stream (file position indicator), che coincide con l’indice del prossimo byte che deve essere letto o scritto.

Ogni operazione di I/O modifica la posizione corrente;
La posizione corrente può essere ricavata o modificata direttamente usando particolari metodi.


Gli oggetti stream (segue)

Gli oggetti stream sono organizzati secondo una gerarchia di classi dette genericamente stream.
Ogni classe è specializzata per tipo di operatori di input e output supportati e per il tipo delle sorgenti e destinazioni (file, I/O, stringhe, etc.).


Gli oggetti stream (segue)

cin e cout sono oggetti (globali) rispettivamente delle classi istream e ostream di cui conosciamo già alcuni metodi:

cin>>dato; (operatore di estrazione);
cin.getline(char s[], int n, char c=’\n’)
cin.get (char s[], int n, char c=’\n’).

cout<<dato; (operatore di inserimento)
cout.width(ampiezza);
cout.precision(cifre);

L’operatore punto (.) serve a selezionare un metodo di un oggetto.


I file binari

Abbiamo ora la necessità di conservare i dati sul disco per non doverli riscrivere ogni volta che il programma viene eseguito.

Per gestire le strutture in maniera diretta, introduciamo i file binari.
Ricordiamo che il nome fisico di un file è il nome del file sul disco come è visto dal sistema operativo; il nome logico, invece, è il nome con cui viene gestito dal programma.

Il legame tra file fisico e file logico è dato dal metodo open applicato all’oggetto file (vedi figura).


I file binari (segue)

La classe stream (flusso) è la base per l’I/O in C++.

Come precedentemente accennato essa è formata da una sequenza di byte che fluiscono da un dispositivo all’altro, da cui il termine stream.

La sequenza di byte può fluire dalla tastiera alla memoria centrale del computer: abbiamo così l’input standard, l’oggetto cin, che è un oggetto stream.

Analogamente, l’oggetto cout rappresenta l’output standard, il flusso di dati dalla memoria centrale al monitor.

Agli oggetti cout e cin abbiamo applicato, rispettivamente, gli operatori di inserimento (<<) e di estrazione (>>), un pò come accade ai numeri interi di tipo int a cui applichiamo gli operatori di incremento (++) e decremento (–).

I file binari (segue)

Questi oggetti possono essere gestiti da altri metodi (procedure e funzioni) cui si accede mediante il punto (.), che rappresenta la selezione di un metodo dell’oggetto; per esempio, per leggere una stringa s dalla tastiera scriviamo cin.getline(s,100);

dove cin è l’oggetto, getline il metodo, s la variabile stringa letta dalla tastiera;
il punto che separa cin da getline indica che quel metodo appartiene a quell’oggetto.

I file binari (segue)

Oltre agli oggetti cin e cout, il file <iostream> contiene anche l’oggetto cerr;

cerr è associato al dispositivo di errore standard per cui, se si verifica un errore di I/O, esso viene immediatamente notificato all’output standard (vedi esempio nel paragrafo successivo).

Anche i file sono dei flussi e quindi appartengono alla classe stream; la libreria per la loro gestione è contenuta in <istream>, per quanto concerne l’input ed in <ostream> per l’output;

se si ha la necessità di eseguire funzioni di lettura e scrittura si può includere il file <fstream> che le contiene entrambe.

I file binari (segue)

Una volta creata la corrispondenza tra file fisico e file logico, il sistema operativo si occuperà di travasare i dati dall’uno all’altro.

Quando ordiniamo di scrivere sul file logico, i dati inviati vengono memorizzati in una zona di memoria temporanea connessa al file stesso. Nel momento in cui tale zona di memoria viene riempita oppure il file viene chiuso, allora il computer provvederà ad inviare tutti i dati al file fisico.

Analogamente, nella fase di lettura, il computer legge dal file fisico una quantità di dati tale da riempire il buffer (oppure legge tutti i dati del file se questi sono in quantità inferiore alla lunghezza del buffer); ogni istruzione di lettura successiva continuerà a leggere dati dal buffer finché esso non si svuota; a quel punto i nuovi dati vengono prelevati dal file ed inseriti nel buffer per essere letti successivamente.

La Sintassi dei file binari

File1.open(nome file fisico, modalità di accesso) dove File1 è una variabile di tipo fstream.

nome file fisico è il nome, comprensivo del path, con cui è conosciuto dal sistema operativo,
modalità di accesso può assumere uno dei seguenti valori:

Modalità di accesso  →  Descrizione
ios::in → Apre il file per la lettura.
ios::out →  Apre il file per la scrittura.
ios::ate →  Apre il file posizionandosi alla fine del file.
ios::app →  L’output viene aggiunto alla fine del file.
ios::trunc →  Se il file esiste viene cancellato scrivendoci sopra.
ios::binary →  Accesso in modalità binaria.

La Sintassi dei file binari (segue)

La classe ios è la capostipite di tutte le classi di I/O.
Tutte le altre classi di I/O come ifstream, ofstream, fstream, ……. derivano da essa.

Per poter utilizzare questa proprietà è necessario servirsi del namespace della classe, ios, seguito dall’operatore di scope:: per cui, ad esempio, la scrittura

ios::in

indica che il file sarà aperto soltanto in lettura, che è la modalità standard per i file dichiarati come ifstream.

Si possono combinare varie modalità di accesso con l’operatore | (OR ) tra bit.
Per esempio, la modalità di default di apertura di un file in scrittura è

ios::out | ios::trunc

perché in un file di tipo ofstream si può scrivere soltanto dopo aver cancellato tutto in quanto il puntatore di scrittura si dispone ad inizio file.

La Sintassi dei file binari (segue)

Oltre le classi ifstream e ofstream esiste la classe fstream che consente di aprire un file sia in lettura che in scrittura; alcuni compilatori aprono un file di tipo fstream con le seguenti modalità di default

ios::in | ios::out

I file di testo, sono gestiti in maniera sequenziale: per ricercare un dato è necessario scorrere tutte le celle iniziando dalla prima, mentre l’inserimento di un dato può avvenire soltanto alla fine.

.

La Sintassi dei file binari (segue)

Il C++ gestisce anche i file ad accesso diretto in cui è possibile posizionarsi in qualsiasi punto all’interno di essi.
Per questo tipo di file sono necessari due puntatori, uno che indica la posizione di lettura ed un altro quello di scrittura.
Ci sono inoltre funzioni che consentono di leggere e scrivere in una qualsiasi posizione all’interno del file.
Questi file, che hanno una struttura profondamente diversa dai file di testo, sono detti file binari.

La Sintassi dei file binari (segue)

I file binari possiedono due puntatori, uno in lettura ed uno in scrittura, che si posizionano esattamente nel punto successivo in cui va effettuata l’operazione; il puntatore di lettura punta al prossimo elemento da leggere, il puntatore di scrittura punta alla locazione in cui va scritto il successivo elemento.
Quanto detto vale non solo per i file ma per qualsiasi stream, per cui si utilizzano spesso i termini:

  • get stream pointer per il puntatore di lettura
  • put stream pointer per quello di scrittura.

Per questa ragione, le funzioni che leggono i dati hanno un carattere g(et) alla fine, mentre le funzioni di scrittura hanno una lettera p(ut).

La Sintassi dei file binari (segue)

Le funzioni da utilizzare per posizionare il puntatore all’interno del file binario sono le seguenti:

Funzioni (metodi)  →  Descrizione

tellg() → Questo metodo non richiede parametri; ritorna un intero che rappresenta la posizione del puntatore di lettura.

tellp() →  Anche questo metodo non richiede parametri; ritorna un intero che rappresenta la posizione del puntatore di scrittura.

seekg(long pos) →  Questo metodo posiziona il puntatore di lettura nella posizione   pos
Ricordiamo che la posizione parte dal valore 0.

seekp(long pos) →  Questo metodo posiziona il puntatore di scrittura nella posizione  pos.

La Sintassi dei file binari (segue)

I due metodi, seekg e seekp, possono essere sovraccaricati con altre due funzioni che stabiliscono anche la direzione in cui muovere il puntatore:
seekg( long pos, direzione)
seekp( long pos, direzione)

dove direzione può assumere uno dei valori seguenti:

Direzione  →  Descrizione
ios::beg →  Il valore del parametro pos è calcolato dall’inizio del file (è la condizione di default).
ios::cur →  Il valore del parametro pos è calcolato dalla posizione corrente.
ios::end →  Il valore del parametro pos è calcolato dalla fine del file e quindi, se si vuole leggere, deve essere un numero negativo.

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion