Classi c++
Classi c++
Salve ragazzi, volevo chiedere una mano a qualcuno nel campo liste c++.
Guardate l'esercizio 5 di questo esame passato http://www2.ing.unipi.it/~d8669/didatti ... 7-2008.pdf
quando nell'int main mi dice A*pa=new c(3); do il giusto output, poi alla riga dopo mi dice pa->f() ma qui a quale funzione si riferisce d quale classe? E per quanto riguarda i disruttori in che ordine verngono chiamati?
spero mi sapete aiutare...
Guardate l'esercizio 5 di questo esame passato http://www2.ing.unipi.it/~d8669/didatti ... 7-2008.pdf
quando nell'int main mi dice A*pa=new c(3); do il giusto output, poi alla riga dopo mi dice pa->f() ma qui a quale funzione si riferisce d quale classe? E per quanto riguarda i disruttori in che ordine verngono chiamati?
spero mi sapete aiutare...
...Meglio un terminale oggi Che un Crash oggi e domani...E dopodomani....
- daemon_nio
- Entusiasta Emergente

- Messaggi: 1012
- Iscrizione: lunedì 15 gennaio 2007, 14:18
- Sesso: Maschile
- Località: London
- Contatti:
Re: Classi c++
Allora cerco di commentarti un po' il codice e il risultato:
l'istruzione
produce:
Dove la prima, seconda e quarta istruzione sono facilmente intuibili (c'ero arrivato anche senza eseguire il codice
), infatti sono le chiamate ricorsive ai costruttori. Quando crei un oggetto di classe C che deriva la classe B che deriva la classe A vengono richiamati i costruttori in maniera inversa (prima A, poi B, poi C ognuno dei quali stampa a video la scritta, nota che nel costruttore C c'è anche l'incremento delle variabili perciò stampa 4). La terza stampa era più difficile da intuire, come vedi nella classe C c'è la variabile A aa che viene istanziata prima della chiamata al costruttore (e non passando nessun parametro viene inizializzato il valore a con quello di default: 0 ) Da notare anche che A* pa = new C(3); dichiara il tipo di pa come A (classe madre) ma lo istanzia con new C(3) (classe figlia): questo è il polimorfismo.
l'istruzione:
produce:
Semplice: il polimorfismo dice che viene richiamato il metodo della classe con cui è stata instanziato l'oggetto (classe figlia C) quindi stai richiamando C::F() e non il metodo della classe con cui è stato dichiarato l'oggetto (classe madre A). (La richiami con l'operatore -> in quanto pa è un puntatore)
l'istruzione:
produce:
Stesso identico discorso della prima istruzione.
l'istruzione:
produce:
Anche qui il polimorfismo fa in modo che venga chiamato il metodo della classe C anche se l'oggetto è dichiarato di tipo B.
l'istruzione:
produce:
Questo perché i distruttori vengono richiamati in maniera inversa ai costruttore. Per lo stesso discorso fatto nella discussione dei costruttori le stampe delle righe 1,3,4 sono intuitive (prima il distruttore di C elimina la parte propria di C, poi viene invocato il distruttore di B, poi il distruttore di A). La 2° riga invece indica la distruzione dell'attributo A aa della classe C (anche questo non è molto intuitivo)
l'istruzione:
produce:
stesso identico discorso di sopra.
Riflessioni totali:
1) mi hai permesso di ripetere un po' le classi in CPP, e per questo te ne sono grato (b2b)
2) probabilmente avrei sbagliato solo la stampa di quella riga un po' antipatica creata dalla variabile aa della classe C (mettendola da qualche altra parte io avrei pensato sempre per ultimo)
3) se all'esame fai solo quell'errore lo passi di sicuro
4) Nota i metodi virtuali della classe A, significa che DEVONO essere assolutamente ridefiniti da una sottoclasse.
Spero ti abbia eliminato qualche dubbio.
In bocca al lupo per l'esame.
l'istruzione
Codice: Seleziona tutto
A* pa = new C(3);Codice: Seleziona tutto
A : a = 3
B: b = 3
A : a = 0
C: a = 4
l'istruzione:
Codice: Seleziona tutto
pa->f();Codice: Seleziona tutto
C::f() b = 4l'istruzione:
Codice: Seleziona tutto
B* pb = new C(2);Codice: Seleziona tutto
A : a = 2
B: b = 2
A : a = 0
C: a = 3
l'istruzione:
Codice: Seleziona tutto
pb->f();Codice: Seleziona tutto
C::f() b = 3l'istruzione:
Codice: Seleziona tutto
delete pa;Codice: Seleziona tutto
via C
via A
via B
via Al'istruzione:
Codice: Seleziona tutto
delete pb;Codice: Seleziona tutto
via C
via A
via B
via ARiflessioni totali:
1) mi hai permesso di ripetere un po' le classi in CPP, e per questo te ne sono grato (b2b)
2) probabilmente avrei sbagliato solo la stampa di quella riga un po' antipatica creata dalla variabile aa della classe C (mettendola da qualche altra parte io avrei pensato sempre per ultimo)
3) se all'esame fai solo quell'errore lo passi di sicuro
4) Nota i metodi virtuali della classe A, significa che DEVONO essere assolutamente ridefiniti da una sottoclasse.
Spero ti abbia eliminato qualche dubbio.
In bocca al lupo per l'esame.
Ultima modifica di daemon_nio il sabato 6 settembre 2008, 23:40, modificato 1 volta in totale.
Sempre costruendo qualcosa di nuovo: Matag: The Game
Re: Classi c++
Grazie sei stato molto utile ti volevo chiedere un ultima cosa,quando leggo accanto ad una funzione o accanto ad un distruttore la parola virtual mi devo comportare in maniera diversa? Guarda questo altro testo d'esame ,ti ringrazio per la grande disponibiltà http://www2.ing.unipi.it/~d8669/didatti ... 2-2006.pdf
...Meglio un terminale oggi Che un Crash oggi e domani...E dopodomani....
- daemon_nio
- Entusiasta Emergente

- Messaggi: 1012
- Iscrizione: lunedì 15 gennaio 2007, 14:18
- Sesso: Maschile
- Località: London
- Contatti:
Re: Classi c++
A quanto ricordo se un metodo (o anche distruttore) viene dichiarato virtuale significa che quando lo ridefinisci lo sovraccarichi anche.
Se avessi avuto (mi riferisco all'esercizio 1):
invocando su un oggetto di tipo B la funzione stampa avresti avuto la doppia stampa (prima del metodo A::stampa() poi del metodo B::stampa() ).
Dichiarando invece virtuale il metodo stampa di A quando lo ridefinisci in B e lo richiami su di un oggetto di tipo B stai dicendo di voler eseguire solo B::stampa() senza eseguire prima A::stampa(). Quindi i metodi virtuali è come se non venissero ereditati.
Questo è quel che ricordo io... però ti conviene aspettare anche la conferma di qualcun altro o di dare uno sguardo a qualche testo.
Se avessi avuto (mi riferisco all'esercizio 1):
Codice: Seleziona tutto
class A
{...
public:
...
void stampa(){cout << "stampa A:" << x << endl;}
};
class B: public A
{...
public:
...
void stampa(){cout << "stampa B: " << x << endl;}
};
Dichiarando invece virtuale il metodo stampa di A quando lo ridefinisci in B e lo richiami su di un oggetto di tipo B stai dicendo di voler eseguire solo B::stampa() senza eseguire prima A::stampa(). Quindi i metodi virtuali è come se non venissero ereditati.
Questo è quel che ricordo io... però ti conviene aspettare anche la conferma di qualcun altro o di dare uno sguardo a qualche testo.
Sempre costruendo qualcosa di nuovo: Matag: The Game
Re: Classi c++
DAemon sei veraemnte molto disponibile,ho dato una letta ad un libro di testo poi ho provato a fare un nuovo esercizio,ho capito bene le chiamate dei costruttori ricorsive ma meno le chiamate di funzioni.. http://www2.ing.unipi.it/~d8669/didatti ... 9-2006.pdf
quando chiama pa->f() da a:f() x=7 ma perchè 7?
quando invece da pc->f() richiama normalmente la funzione f di della classe C.
quando chiama pa->f() da a:f() x=7 ma perchè 7?
quando invece da pc->f() richiama normalmente la funzione f di della classe C.
...Meglio un terminale oggi Che un Crash oggi e domani...E dopodomani....
-
Dahman
- Entusiasta Emergente

- Messaggi: 1013
- Iscrizione: mercoledì 31 ottobre 2007, 8:29
- Località: Torino
Re: Classi c++
perché in realtà ci sono due x:quando chiama pa->f() da a:f() x=7 ma perchè 7?
quella dichiarata pubblica in A quindi visibile da tutte le classi
e quella dichiarata in C privata quindi visibile solo da C.
Inoltre la f() é virtual solo sotto B.
Una volta definito l'oggetto A *pa = new C, esso ha 2 x, quella privata che vale (sempre) 2 e quella pubblica che vale 7, passando per 5.
pa->f() esegue la funzione A::f() perché non virtual quindi restituisce l'unica x che A riesce a vedere, cioé 7. Ed ecco spiegato il risultato.
Spero di esserti utile
Ciao
Dahman
Chi c’è in linea
Visualizzano questa sezione: 0 utenti iscritti e 4 ospiti
