/* Oltre ai metodi, possiamo sovrapporre (overload) anche i costruttori.
* Supponiamo di voler rendere facoltativi i parametri del costruttore della
* classe animale:
*
* class animale { // Definisco la classe animale
* ...
* public: // La parte che segue e' PUBLIC (visibile da tutti)
* animale(void); // Costruttore: nessun parametro
* animale(int zamp); // Costruttore: 1 par.: int zamp
* animale(int zamp, float lungh); // Costruttore: 2 par.: zamp, lung
* ~animale(void); // Distruttore
* ...
* };
*
* // Ecco il costruttore senza parametri
*
* animale::animale(void)
* {
* lunghezza = 0;
* numerozampe = 0;
* }
*
* // Ecco il costruttore con 1 parametro: int zamp
*
* animale::animale(int zamp)
* {
* lunghezza = 0
* numerozampe = zamp; // Il num. zampe lo metto subito
* }
*
* // Ecco il costruttore con 2 parametri: int zamp, float lung
*
* animale::animale(int zamp, float lung)
* {
* lunghezza = lung;
* numerozampe = zamp;
* }
*
* Ecco infine le possibili dichiarazioni:
*
* animale cane();
* animale cane(4); // Definisco subito che ha 4 zampe
* animale cane(4,40.5) // Definisco subito 4 zampe e lungh. 40.5 cm
*
* Questo rende piu' flessibile l'inizializzazione del nostro oggetto.
* Dato che questa e' solo una applicazione del polimorfismo ai costruttori,
* niente di veramente nuovo, nel listato e' sfruttata una nuova possibilita'
* permessa dal C++: la dichiarazione "al volo" di variabili all'interno di
* un blocco, anziche' solo al suo inizio. Cio' e' illegale in C.
* Un momento! Gli oggetti (classi), allora, non possono essere dichiarati
* in un qualsiasi punto del listato, anziche' solo all'inizio?
* Si! Basta chiamare i costruttori dove piu' ci pare.. o meglio al momento
* che l'oggetto ci servira'. Questo permette di assegnare all'oggetto
* (tramite il costruttore con parametri) dei valori che sappiamo solo in
* un certo punto del listato, e non all'inizio.
* Per esempio, possiamo creare l'oggetto animale quando sappiamo il numero
* delle sue zampe, e non all'inizio, quando non lo sappiamo e non possiamo
* fare altro che inizializzare tutto a zero, aspettando che il valore
* venga immesso dal metodo mettizampe().
* In questo listato quindi "mixeremo" e inizializzeremo dinamicamente sia
* le variabili che le classi, sfruttando la nuova liberta' permessa dal C++.
*/
#include <iostream.h> // Header necessario per usare CIN e COUT
// Questo e' un commento C++ ad una sola linea
class animale { // Definisco la classe animale
float lunghezza; // Questa parte e' PRIVATE di default
int numerozampe;
public: // La parte che segue e' PUBLIC (visibile da tutti)
animale(void); // Costruttore: nessun parametro
animale(int zamp); // Costruttore: 1 par.: int zamp
animale(int zamp, float lungh); // Costruttore: 2 par.: zamp, lung
~animale(void); // Distruttore
void mettilungh(float i); // I prototipi dei metodi della
void mettizampe(int l); // nostra classe.
float leggilungh(void);
int leggizampe(void);
};
// Ora scriviamo le funzioni (metodi) della classe animale:
// Ecco il costruttore senza parametri
animale::animale(void)
{
lunghezza = 0;
numerozampe = 0;
}
// Ecco il costruttore con 1 parametro: int zamp
animale::animale(int zamp)
{
lunghezza = 0;
numerozampe = zamp; // Il num. zampe lo metto subito
}
// Ecco il costruttore con 2 parametri: int zamp, float lung
animale::animale(int zamp, float lung)
{
lunghezza = lung;
numerozampe = zamp;
}
// Ecco il distruttore
animale::~animale(void)
{
cout << "animale distrutto\n";
}
/*-------------------------------------------------------------------------*
* mettilungh: definisce la lunghezza dell'animale.
* parametri: in entrata la lunghezza in formato float.
*-------------------------------------------------------------------------*/
void animale::mettilungh(float i)
{
lunghezza = i; // Scrive il valore nella variabile privata "lunghezza".
}
/*-------------------------------------------------------------------------*
* mettizampe: definisce il numero di zampe dell'animale.
* parametri: in entrata il num. di zampe in formato int.
*-------------------------------------------------------------------------*/
void animale::mettizampe(int l)
{
numerozampe = l; // Scrive il valore nella variabile privata "numerozampe".
}
/*-------------------------------------------------------------------------*
* leggilungh: legge e restituisce la lunghezza dell'animale.
* parametri: in uscita la lunghezza in formato float.
*-------------------------------------------------------------------------*/
float animale::leggilungh(void)
{
return lunghezza;
}
/*-------------------------------------------------------------------------*
* leggizampe: legge e restituisce il num. di zampe dell'animale.
* parametri: in uscita il num. di zampe in formato int.
*-------------------------------------------------------------------------*/
int animale::leggizampe(void)
{
return numerozampe;
}
///////////////////////////////////////////////////////////////////////////
// Il main...
///////////////////////////////////////////////////////////////////////////
int main(void)
{
// Da notare che iniziamo il programma senza aver dichiarato ne' classi,
// ne' variabili!! Chiediamo all'utente di darci le informazioni.
cout << "Num. zampe cane 1? "; // Stampa la frase.
// Oooops! ci serve la variabile temp2! No prob., si puo' dichiarare ora.
int temp2; // Variabile temporanea che usiamo per il num. zampe. Da
// notare che la abbiamo definita dopo un'istruzione, e
// non all'inizio. Questo e' illegale in C, ma legale in C++
cin >> temp2; // Legge il valore.
// 2*Ooops! E l'oggetto? dichiariamone uno al volo, vah...
animale cane1; // Istanzio cane1, senza passare parametri al costr.
cane1.mettizampe(temp2); // Passa a mettizampe la variabile temp2
cout << "Lunghezza cane 1? "; // Stampa la frase come un printf()
float temp; // Var. temporanea per la lunghezza.
cin >> temp; // Legge il valore come scanf()
cane1.mettilungh(temp); // Passa a mettilungh la variabile temp
// Veniamo al secondo oggetto. Le variabili temp e temp2 ormai ci sono gia'.
// Qua comunque siamo piu' "furbi", perche' passiamo direttamente al
// costruttore il num. di zampe, evitando di chiamare mettizampe().
cout << "Num. zampe cane 2? "; // Stampa la frase come un printf()
cin >> temp2; // Legge il valore come scanf()
cout << "Lunghezza cane 2? "; // Stampa la frase come un printf()
cin >> temp; // Legge il valore come scanf()
animale cane2(temp2); // Istanzio cane2, passando al cost. il num. zampe
cane2.mettilungh(temp); // Passa a mettilungh la la lunghezza.
// Il millepiedi lo definiamo in un sol colpo usando il costruttore con 2
// parametri, definito prima sovrapponendolo (overload) agli altri 2.
animale millepiedi(1000,3); // Istanzio millepiedi, passando il num.
// zampe e la lunghezza al costruttore.
// Ora visualiziamo lo stato degli animali, usando i loro metodi di lettura.
cout << "\nStato del cane1: zampe = " << cane1.leggizampe();
cout << ", lunghezza = " << cane1.leggilungh();
cout << "\nStato del cane2: zampe = " << cane2.leggizampe();
cout << ", lunghezza = " << cane2.leggilungh();
cout << "\nStato del millepiedi: zampe = " << millepiedi.leggizampe();
cout << ", lunghezza = " << millepiedi.leggilungh() << "\n";
return 0; // main() restituisce 0
}
/* A questo punto si potrebbero "overloadare" anche i metodi, permettendo
* di inserire altri dati, facoltativamente... se volete fatelo voi.
* Per quanto riguarda la nuova dichiarazione delle variabili, possibile
* anche nel punto del listato dove sono utilizzate, e' evidente lo spirito
* Object Oriented dell'incapsulation di codice e' dati.
* Inoltre cio' rende possibile l'inizializzazione dinamica, ossia e'
* possibile assegnare alla variabile che si crea il risultato di una
* espressione calcolata precedentemente, magari diversa ogni volta:
*
* cout << "Lunghezza di 2 Pippi? "; // Stampa la frase come un printf()
* cin >> temp; // Legge il valore come scanf()
* int pippo = temp/2; // Creo un int e lo inizializzo dinamicamente
*
* La variabile pippo e' creata e inizializzata con un valore diverso per
* ogni esecuzione del programma (dipende da cosa scrive l'utente).
* Lo stesso vale per i costruttori parametrici delle classi.
*/
