|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Sep 2005
Messaggi: 120
|
C++ - Non mi è chiara una cosa sulle funzioni virtuali
perchè questo codice
Codice:
#include <iostream> using namespace std; class B { protected: int b; public: void f1() {cout << 'B' << endl;} } ; class D: public B { public: virtual void f1(){ cout << 'D' << endl;} }; int main(){ D* pd = new D; pd->f1(); system("PAUSE"); return 0; } ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2003
Messaggi: 980
|
Codice:
#include <iostream> using namespace std; class B { protected: int b; public: virtual void f1() {cout << 'B' << endl;} } ; class D: public B { public: virtual void f1(){ cout << 'D' << endl;} }; int main(){ B* pd = new D; pd->f1(); system("PAUSE"); return 0; } ![]() 1) la parola virtual deve essere usata nella classe base! Nella classe derivata puoi anche ometterla. 2) Perchè tutto l'ambaradan funzioni devi usare un puntatore o riferimento alla classe derivata e "memorizzarla" in un puntatore o riferimento della classe base: Codice:
B* pd = new D; ![]() Ultima modifica di kk3z : 06-01-2007 alle 08:58. |
![]() |
![]() |
![]() |
#3 |
Utente sospeso
Iscritto dal: Oct 2002
Messaggi: 2156
|
stampa D perchè stai chiamando un metodo della classe D che stampa appunto D
![]() sono stato chiaro?
__________________
sign editata dallo staff |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Apr 2003
Città: Genova
Messaggi: 4741
|
Quote:
![]() dichiarare il metodo nella classe D (la tua derivata) come virtual, non informa il compilatore che ne esiste un' altra implementazione nella classe da cui D deriva, e di usare quella lo informa che la classe D verrà molto probabilmente ereditata a sua volta in una terza classe, molto probabilmente dotata di una propria (re)implementazione di f1() che offuscherà (si parla di override) quella presente in D in effetti, anche se avessi usato la stesura (corretta ![]() EDIT: ho notato dopo che BountyKiller si è spiegato in termini più chiari di me ![]() forse ai fini dell' assimilazione del polimorfismo si potrebbe scrivere un esempio leggermente migliore Codice:
#include <iostream> using namespace std; class B { protected: int b; public: virtual void f1(); } ; class D1: public B { public: virtual void f1(){ cout << 'D1' << endl;} }; class D2: public B { public: virtual void f1();{ cout << 'D2' << endl;} }; int main(){ B* pd1 = new D1; B* pd2 = new D2; pd1->f1(); pd2->f1(); system("PAUSE"); return 0; }
__________________
Jappilas is a character created by a friend for his own comic - I feel honored he allowed me to bear his name Saber's true name belongs to myth - a Heroic Soul out of legends, fighting in our time to fullfill her only wish Let her image remind of her story, and of the emotions that flew from my heart when i assisted to her Fate
Ultima modifica di jappilas : 06-01-2007 alle 10:44. |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2006
Città: Bergamo
Messaggi: 2499
|
aggiugo a scopo didattico che se dichiari:
Codice:
class B { protected: int b; public: virtual void f1() = 0; } ; Ultima modifica di vizzz : 06-01-2007 alle 18:29. |
![]() |
![]() |
![]() |
#6 |
Member
Iscritto dal: Sep 2005
Messaggi: 120
|
grazie mille, siete stati molto esaurienti, però vorrei capire un'ultima cosa: nel caso che dico io la funzione viene scelta a tempo di compilazione? insomma al compilatore non gliene frega nulla che sia virtuale o no, prende la classe D nella quale la funzione f1 della classe derivata "sovrascrive" quella della classe base e tranquillamente esegue senza vtable e roba del genere, giusto? Insomma i vantaggi concreti delle virtuali sono che posso usare un puntatore del tipo della classe base inizializzato con classi derivate per richiamare funzioni delle classi derivate, per il resto non cambia nulla...
a proposito, jappilas, il codice tuo non va perchè la funz nella classe base o la definisci o la metti virtuale pura (vero vizzz?). |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2006
Città: Bergamo
Messaggi: 2499
|
Quote:
|
|
![]() |
![]() |
![]() |
#8 | |||
Senior Member
Iscritto dal: Apr 2003
Città: Genova
Messaggi: 4741
|
Quote:
In questo caso è possibile che il compilatore abbia bisogno sia del lookup alla vtable, sia del cosiddetto fixup del puntatore this Quote:
comunque sì, è il polimorfismo ed è una delle caratteristiche fondanti della programmazione object oriented (per come mi fu insegnata almeno) ![]() Quote:
l' idea era di ottenere un esempio leggermente migliore sull' ereditarietà modificando poco il codice originale (tuo) ... e spronarti alla ricerca degli errori, ma vedo che hai già risposto ![]()
__________________
Jappilas is a character created by a friend for his own comic - I feel honored he allowed me to bear his name Saber's true name belongs to myth - a Heroic Soul out of legends, fighting in our time to fullfill her only wish Let her image remind of her story, and of the emotions that flew from my heart when i assisted to her Fate
Ultima modifica di jappilas : 07-01-2007 alle 13:23. |
|||
![]() |
![]() |
![]() |
#9 |
Member
Iscritto dal: Sep 2005
Messaggi: 120
|
grazie, scusa per il ritardo della risposta ma ero impegnato con gli esami... che sono andati bene grazie anche a questo chiarimento...
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:01.