Funzioni virtual

di il
73 risposte

73 Risposte - Pagina 4

  • Re: Funzioni virtual

    Mi potreste aiutare
  • Re: Funzioni virtual

    dna_programmer ha scritto:


    cioè forse mi sono spiegato male io; non è che non ho mai visto una funzione che ritorna qualcosa ma non ho mai visto una funzione che ha un puntatore
    Intendi dire che non hai mai visto una funzione che ritorna un puntatore? Un funzione può ritornare puntatori senza problemi anzi è un uso molto frequente, si scrive ad esempio:
    
    MyClass* FunzioneCheCreaERitornaUnMyClass()
    {
       MyClass* p = new MyClass();
       // ... fa qualcosa su p, ad esempio lo inizializza 
       return p;
    }
    
    Non dimenticarti che un MyClass* può contenere anche riferimenti a classi che derivano da MyClass, quindi si potrebbe avere:
    
    MyClass* FunzioneCheCreaERitornaUnMyClass()
    {
       if (miVaDiRitornareUnDerivato)
            return new MyClassDerived();
        else
            return new MyClass();
    }
    
  • Re: Funzioni virtual

    Ciao, cioè quindi nel secondo esempio se è true la if allora la MyClass punta a Myclassderived
    altrimenti punta a se stessa( a my Class).
    Ho capito bene?
  • Re: Funzioni virtual

    Si, ora ripeto il concetto con altre parole ma la sostanza è quella.
    
       MyClass* p = FunzioneCheCreaERitornaUnMyClass();
    
    La funzione 'FunzioneCheCreaERitornaUnMyClass()' alloca un oggetto di tipo MyClass oppure un oggetto di tipo MyClassDeriver e ne restituisce l' indirizzo in un puntatore di tipo MyClass*.

    Nel puntatore 'p' possiamo avere l' indirizzo di un oggetto di tipo MyClass oppure l' indirizzo di un oggetto di una qualsiasi classe derivata da MyClass.

    Quindi ricorda la regola: un puntatore ad una classe puo puntare ad una istanza di quella classe o a una istanza di una classe derivata. (il succo del polimorfismo è tutto qui)
  • Re: Funzioni virtual

    A ecco, si ho fatto alcune prove pratiche è devo dire che va tutto bene, finalmente ho capito(almeno speriamo). Comunque di nuovo grazie per la vostra disponibilità e la pazienza.

    Ultima cosa:

    quindi facendo un riassunto del polimorfismo, esso è una tecnica della OOP che permette, quando si ha una classe base e varie classi derivate, tramite i puntatori e le funzioni virtuali di far assumere risultati diversi ai vari metodi in base a quale classe punta la classe base(nel nostro caso), quindi rende il tutto più dinamico.
    Spero sia così
  • Re: Funzioni virtual

    Si, hai capito.
    Pensavo di chiudere qui il discorso perchè ormai il concetto ti è chiaro, però la frase che hai scritto è scorretta e contiene degli errori, anche se il senso c' è. Te li segnalo giusto per completezza:

    non: far assumere risultati diversi ai vari metodi in base ...
    ma: richiamare metodi diversi in base ...

    I metodi non assumono valori, vengono richiamati.

    non: in base a quale classe punta ...
    ma: in base al tipo dell' istanza a cui punta ...

    Un puntatore non punta a una classe ma ad una istanza di una certa classe.

    non: a cui ... punta la classe base ...
    ma: a cui ...punta il puntatote di tipo classe base ...

    Una classe non punta nulla, è un puntatore di qualche tipo che punta a qualcosa.

    La frase con queste correzioni diventerebbe:
    'richiamare metodi diversi in base al tipo dell' istanza a cui punta il puntatote di tipo classe base.'
    Non è molo bella neppure lei però è corretta:
  • Re: Funzioni virtual

    A ok grazie ancora, io purtroppo con le definizioni non sono mai stato una cima , peró l'importante che ho capito l'argomento. Ultimissima cosa, quindi in pratica il polimorfismo senza i puntatori è un po "castrato"? Giusto?
  • Re: Funzioni virtual

    Ciao dna_programmer,
    Esatto il polimorfismo si basa sui puntatori, tanto che in altri linguaggi, ad es. Java, VisualBasic, C# puoi utilizzare gli oggetti 'solo' tramite puntatori.
  • Re: Funzioni virtual

    Però senza sapere che li stai usando perché uno ad esempio dichiara:

    rettangolo x = new rettangolo(2,3)

    in questo caso però non si vede l'uso dei puntatori, ma soltanto una normale istanza di una classe
  • Re: Funzioni virtual

    Ciao dna_programmer,
    la riga che hai scritto non si compila, manca un '*', bisogna scrivere:
    
    rettangolo* x = new rettangolo(2,3);
    
    Non è detto che ogni volta che usi i puntatori tu sia intenzionato ad usare il polimorfismo, il più delle volte li usi per altri motivi. Nell' esempio che hai scritto semplicemente crei un rettangolo e poi lo assegni a un puntatore.

    E poi ti ricordi il discorso di assegnare un oggetto ad un puntatore ad una classe base? (non vorrei rifarlo da capo )
    
    shape* x = new rettangolo(2,3);
    x->Draw();
    
    una cosa del genere sarebbe un uso polimorfo.
  • Re: Funzioni virtual

    Scusa mi sono spiegato male io, cioè mi riferivo al framework .NET, nella quale l'uso dei puntatori è nascosto, quindi quando si dichiara un oggetto in realtà si fa uso dei puntatori però è completamente nascosto al programmatore, questo intendevo. mentre in c++ bisogna dichiararlo esplicitamente(mettendo ' * ' )

    VB.net:

    rettangolo x = new rettangolo(2,3)

    C++:

    rettangolo * x= new rettangolo(2,3)

    giusto?


    Infine vediamo se ho capito il tuo esempio:
    
    shape* x = new rettangolo(2,3);
    x->Draw();
    
    In questo caso tu hai una classe base "shape" e una classe figlia rettangolo in cui nel costruttore gli passi, ad esempio, la base e l'altezza. a questo punto tramite i puntatori la classe base punta alla classe figlia(rettangolo), quindi la classe base ha gli stessi metodi e attributi della classe rettangolo; a quel punto l'oggetto shape richiama il metodo "draw", e si presuppone che andrà a disegnare un rettangolo

    Giusto?
  • Re: Funzioni virtual

    L' esempio su VB.net è giusto i puntatori ci sono ma sono nascosti. E l' esempio sul rettandolo è giusto pure lui, la chiamata a Draw disegnarà un rettangolo (o un cerchio) in base a cosa è stato assegnato a 'shape'.
  • Re: Funzioni virtual

    Ok, quindi andando un po' più nel tecnico quando si fa questa dichiarazione:
    
    rettangolo * x = new rettangolo(2,3)
    
    
    si dichiara un puntatore "x" di tipo rettangolo, dichiarato nell stack, che ha l'indirizzo(e quindi punta ) dell'oggetto di tipo rettangolo che sta nella memoria heap. Dico bene?
  • Re: Funzioni virtual

    Si, dici bene.
  • Re: Funzioni virtual

    Spero di non aver contravvenuto alla regola "non riesumare thread datati", ho pensato che questo era sia un thread didattico che non troppo vecchio (3 mesi), mi scuso se dovessi aver sbagliato.

    Ho letto e capito tutti gli esempi che son stati fatti finora. Quello che non mi è chiaro è come "spingersi oltre": gli esempi fatti finora hanno un puntatore dichiarato nel main, e la classe a cui puntare viene assegnata nel main. Come si fa nel caso l'assegnazione debba venire fatta dalle classi?
    Posto un esempio.


    .H:
    class graphic
    {
    	public:
    		graphic();
    		~graphic();
    		static void reshape (int width, int height);
    		static void display (void);
    	protected:
    		virtual void m_renderPrimitive(void)=0;
    
    };
    
    class opening: public graphic
    {
    	public:
    		opening();
    		~opening();	
    	private:
    		void m_renderPrimitive (void);
    };

    .CPP:
    
    
    graphic::graphic(){}
    graphic::~graphic(){}
    
    void graphic::display (void)    //METHOD:	DISPLAY
    {
    	 //Righe di codice che non servono qua
    
    	graph->m_renderPrimitive(); // Render the primitive
    }
    
    

    MAIN:
    int main (int argc, char **argv) 
    {  
    	graphic *graph = new opening();
    	glutInit(&argc, argv);
    	glutInitDisplayMode (GLUT_SINGLE);
    	glutInitWindowSize (700, 400);
    	glutInitWindowPosition (100, 100);
    	
    	window=glutCreateWindow ("Intro");
    	glutDisplayFunc(graph->display);
    	glutReshapeFunc(graph->reshape);
    
    	glutMainLoop();
    	return 0;
    }  

    Se dichiaro
     graphic *graph
    nel main, mi dà errore perchè dice 'graph was not declared in this scope'. Penso allora sia da dichiarare static all'interno della classe graph, ma mi dà errore probabilmente perchè non lo faccio nel modo giusto. Qualcuno avrebbe il buon cuore di spiegarmelo?
    Praticamente la funzione a cui punta, la m_renderPrimitive(), è una funzione di 3-4 classi derivate. A seconda di ciò che faccio, ognuna di queste classi deve poter cambiare il puntatore. Avevo pensato di dichiararlo come puntatore statico di graphic in modo che esista indipendentemente dall'oggetto, e accessibile così da tutte le classi derivate, ma non so come farlo... (lo so fare ma con i metodi) Grazie ancora!
Devi accedere o registrarti per scrivere nel forum
73 risposte