| prof. Nunzio Brugaletta |
C++:
programmazione e oggetti |
Nel programma di gestione dei prestiti, per come presentato fino ad ora, si interagisce con oggetti della classe libro, che reagivano in un certo modo, definito dai metodi, ai messaggi inviati. Per esempio, volendo effettuare un prestito, si invia il messaggio prestito() ad un oggetto della classe e questo, risponde modificando un indicatore (il valore conservato nella variabile protetta presente).
Nella programmazione ad oggetti, così come con gli oggetti della vita reale quando si interagisce con essi, se si desidera un effetto diverso basta utilizzare un oggetto diverso. Per esempio se si utilizza una matita per scrivere, qualora si volesse un segno più duraturo, occorrerebbe utilizzare una penna. Parafrasando il modo di esprimersi della OOP, si direbbe che il messaggio inviato all'oggetto resta sempre lo stesso (si sta scrivendo); è l'oggetto che reagisce in modo diverso. Questo è quello che la OOP chiama polimorfismo: caratteristica che consente alle istanze di classi differenti di reagire allo stesso messaggio (una chiamata di funzione) in maniere diverse.
// PRESTITI3: gestione prestiti libri di una biblioteca versione 3
#include <iostream>
#include <string>
using namespace std;
#include "c_libsocio"
#include "c_libreria3" /*1*/
namespace biblioteca{
libreria insertLibri();
void prestito(libreria&);
void restituzione(libreria&);
void info(libreria);
}
int main()
{
biblioteca::libreria biblio; /*2*/
int tipoop;
...
}
Nella nuova revisione del programma di gestione prestiti della biblioteca, viene incluso un nuovo file con una nuova classe (1). Il file c_libreria3, di cui è superfluo riportare il listato, è ottenuto, per il momento, dal file c_libreria cambiando tutte le ricorrenze di libro con libSocio. In tal modo la classe libreria diventa un aggregato di oggetti di tipo libSocio. Si esaminerà più avanti un sistema più elegante, e corretto formalmente, di adattare la classe aggregato al nuovo tipo di oggetti.
Considerate le variazioni riportate non è necessario apportare alcuna modifica alle dichiarazioni di oggetti della classe, come in 2, perché la definizione della classe è la stessa ma fa, ora, riferimento ad oggetti diversi.
// Registrazione libri nella biblioteca
biblioteca::libreria biblioteca::insertLibri()
{
biblioteca::libreria l;
biblioteca::libSocio libtemp; /*1*/
biblioteca::datilib ltemp;
...
libtemp.setLibro(ltemp); /*2*/
l.aggiungi(libtemp);
}
return l;
}
Anche la funzione di inserimento libri non subisce alcuna variazione rispetto alla versione precedente perché in sede di inserimento libri, il socio non interviene. Nella 2 si richiama il metodo per l'inserimento del libro, valido per oggetti della classe libro, ma anche per oggetti della classe libSocio poiché quest'ultima eredita i metodi della classe genitrice libro. Si fa notare che i dati del socio sono inizializzati a stringhe nulle e ciò in virtù della definizione 1 e del fatto che è definito, nella classe, un costruttore che provvede a ciò già a partire dall'esistenza di un oggetto della classe, cioè dalla 1.
// Prestito di un libro
void biblioteca::prestito(libreria& l)
{
int quale,posultimo;
biblioteca::libSocio lib;
biblioteca::datisoc stemp;
posultimo = l.dotazione()-1;
cout << "\nQuale libro (0," << posultimo << ")? ";
cin >> quale;
if (l.estrai(quale,lib)){
if(!lib.getInPrestito()) /*1*/
cout << "Libro gia\' prestato" << endl;
else{
cout << lib; /*2*/
cin.ignore();
cout << "Nome socio :";
getline(cin,stemp.nome); /*3*/
cout << "Cognome socio :";
getline(cin,stemp.cognome); /*3*/
cout << "Recapito socio :";
getline(cin,stemp.via); /*3*/
if(lib.prestato(stemp)){ /*4*/
l.aggiorna(quale,lib);
cout << "\nPrestito registrato" << endl;
}
else
cout << "\nLibro non presente" << endl;
}
}
else
cout << "\nLibro inesistente" << endl;
}
La funzione che gestisce il prestito di un libro è quella che subisce le maggiori modifiche.
Intanto (1) si verifica la disponibilità al prestito del libro. Dopo essersi accertati della esistenza, e disponibilità, del libro richiesto e aver stampato i dati del libro interessato (2), si acquisiscono, per mezzo delle 3, i dati del socio e si invia il messaggio prestato (4) ad un oggetto della classe libSocio. L'oggetto risponde, per come ridefinito il metodo, modificando il flag presente del libro e aggiungendo i dati del socio.
// Restituzione di un libro prestato
void biblioteca::restituzione(libreria& l)
{
biblioteca::libSocio lib; /*1*/
...
if(lib.restituito()){ /*2*/
...
}
La funzione che gestisce la restituzione del libro, non necessita di alcuna modifica. È il metodo richiamato in 2, ora inviato ad oggetti di tipo diverso (1), che si occupa dei nuovi compiti.
// Informazioni su libro
void biblioteca::info(libreria l)
{
biblioteca::libSocio lib; /*1*/
int quale,posultimo;
...
if(l.estrai(quale,lib)) /*2*/
cout << lib; /*3*/
...
}
La funzione di visualizzazione è identica alla corrispondente della versione precedente. L'unica modifica riguarda gli oggetti elaborati (1).
L'estrazione di dati (2) e la stampa (3) si occupano stavolta di oggetti di tipo libSocio. I metodi reagiscono adattandosi alle specifiche della nuova classe.
| http://ennebi.solira.org |
ennebi@solira.org |