// ex12_3_3.cpp #include <iostream.h> // classe base class Palazzo { char* indirizzo; double valoreCatastale; public: Palazzo (char* Indirizzo, double ValoreCatastale) { indirizzo = new char[strlen(Indirizzo)]; strcpy (indirizzo, Indirizzo); valoreCatastale = ValoreCatastale; } ~Palazzo () { delete[] indirizzo; } double getValore () const { return valoreCatastale; } char* getIndirizzo () const { return indirizzo; } }; // classe derivata class Albergo : public Palazzo { unsigned numCamere; unsigned numStelle; public: Albergo (char* Indirizzo, double ValoreCatastale, unsigned NumCamere, unsigned NumStelle) // inizializzazione classe base : Palazzo (Indirizzo, ValoreCatastale), // inizializzazione membri privati numCamere (NumCamere), numStelle (NumStelle) { } ~Albergo () { } unsigned getCamere () const { return numCamere; } unsigned getStelle () const { return numStelle; } }; ostream& operator<< (ostream& os, Palazzo& pal) { os << "palazzo in " << pal.getIndirizzo() << "\ndal valore catastale di lire " << pal.getValore(); return os; } void main() { Albergo albergo ("corso Italia, 12", 3000000000.0, 19, 3); cout << albergo << "\n"; // upcasting Palazzo& pal1 = albergo; // upcasting Palazzo* pal2 = &albergo; // upcasting albergo.getStelle (); // pal1.getStelle (); // NO // Albergo& alb1 = pal1; // NO }
Un Albergo
è un Palazzo
, per cui possiamo effettuare senza problemi chiamate alle funzioni pubbliche di Palazzo
su oggetti di tipo Albergo
, come abbiamo già visto. Il concetto di upcasting va oltre: la conversione da un oggetto di tipo Albergo
ad uno di tipo Palazzo
è implicita, senza che venga programmato alcun operatore di conversione. Il meccanismo è sicuro perché sicuramente un Albergo
possiede tutte le caratteristiche di un Palazzo
; naturalmente si ha una perdita di dati, per cui non è possibile effettuare una chiamata del tipo pal1.getStelle()
, in quanto il numero di stelle dell'albergo è una caratteristica peculiare di un Albergo
, mentre pal1
è di tipo Palazzo
.