Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [C++] metodo che chiama un metodo virtual

    Salve a tutti, sto scrivendo delle classi che mi serviranno per risolvere dei problemi di meccanica analitica. Per me sarebbe importante fare una cosa del genere:
    codice:
    //Mathvector è una classe che modella un vettore inteso in senso matematico
    class Base{
    public:
        //costruttori e distruttore
        virtual MathVector NetForce();           //calcola la somma vettoriale di tutte le forze agenti sul corpo
        
          MathVector speed(double seconds);  
         /* vari metodi che utilizzano al loro interno i metodi virtuali.  */
    Protected:
         double mass;
    }
    class Derived: public Base{
         //reimplementare solo i metodi virtuali
    }
    
    MathVector Base::speed(double seconds) //per esempio
    {
         return NetForce()/mass*seconds;
    }
    Pensandola in queso modo io potevo differenziare i vari oggetti in base alle forze agenti su di essi (per esempio la classe derivata potrebbe aggiungere forze dissipative, o reazioni vincolari).
    La domanda è se posso essere sicuro che quando chiamo un metodo non virtuale della classe derivata esso al proprio interno chiami il metodo virtuale esatto.
    Cioè che
    codice:
    Base* base = new Base();
    Base *derived = new Derived();
    base->speed(); //chiami Base::NetForce();
    derived->speed(); //chiami Derived::NetForce();
    Su alcuni test che ho fatto funziona, ma leggendo in giro dicono che questo approccio sia pericoloso e che il comportamento del programma potrebbe essere indefinito: è vero o va bene così?
    Avete mai fatto qualcosa di simile?
    Cambiando approccio dovrei reimplementare praticamente tutti i metodi della classe base, che però sono molti e perderei il vantaggio del poterli derivare da una classe base che astrae il problema di calcolare gli stati di un corpo libero indipendentemente dalle forze/vincoli applicati?

    EDIT:
    In particolare ho trovato un articolo che parlava di una situazione simile alla mia e cito testualmente:
    Il risultato in queste situazioni e` che il comportamento che una classe puo` avere e` molto difficile da controllare e potrebbe essere potenzialmente errato; l'errore legato a situazioni di questo tipo e` noto in letteratura come fragile class problem e puo` essere causa di forti inconsistenze.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381

    Re: [C++] metodo che chiama un metodo virtual

    Originariamente inviato da MegaAlchimista
    La domanda è se posso essere sicuro che quando chiamo un metodo non virtuale della classe derivata esso al proprio interno chiami il metodo virtuale esatto.
    Si. La stessa STL non espone metodi virtuali al chiamante se non internamente. Un esempio è std::streambuf o codecvt.

    ...che il comportamento del programma potrebbe essere indefinito...
    Solo se richiami funzioni virtuali all'interno di costruttori e distruttori. Occhio che la cosa è ricorsiva.

    Avete mai fatto qualcosa di simile?
    Svariate volte.

    EDIT:
    In particolare ho trovato un articolo che parlava di una situazione simile alla mia e cito testualmente:
    Link?
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Scusa il ritardo, non li ho messi subito perchè non ricordavo alla perfezione il regolamento e non ero sicuro che si potessero inserire i link.
    Inizialmente avevo letto QUESTO
    Poi ho trovato questo articolo del Dr. Carlo Pescio, publicato su "computer programming" nel quale però mi sono un po' perso qui.

    Comunque grazie ai miei test, alla tua risposta ed all'ultimo link ho capito che il problema dovrebbe presentarsi solo ed esclusivamente se qualcun altro dovesse derivare la mia classe base senza aver a disposizione il codice (cosa che al momento credo sia impossibile).
    Correggimi se sbaglio?

    Edit:
    Hai ragione, nel costruttore è ricorsivo, perchè chiamo anche il costruttore della classe base.
    Questa tua semplice frase mi ha fatto riflettere su un errore sul quale non mi ero minimamente soffermato, in quanto chiamavo indirettamente proprio il metodo netForce() per inizializzare i vettori accelerazione ed accelerazione angolare rispetto al baricentro del corpo.
    Ora devo riscrivere i costruttori per poter inizializzare questivettori in modo opportuno, ma l'unica soluzione che mi viene in mente è quella di scrivere codice separato per la classe base e per quelle derivate, in questo modo però sulle classi derivate farò un sacco di lavoro inutile, perchè dovrò calcolare il "valore" dell'accelerazionein un modo (come sarebbe nella classe senzaforze dissipative, e/o reazioni vincolari) e poi rifare tutti i calcoli inmodo adeguato e darle il nuovo valore. In realtà non ho problemi di performance ma la cosa mi infastidisce un po', secondo te esiste un metodo più intelligente per risolvere la questione?
    Un metodo per far si che il costruttore della classe derivata e la classe base inizializzino quasi tutte le variabili allo stesso modo, tranne due.

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da MegaAlchimista
    Un metodo per far si che il costruttore della classe derivata e la classe base inizializzino quasi tutte le variabili allo stesso modo, tranne due.
    Un modo un po' complesso ma elegante lo riporta sempre Pescio qui:
    http://www.eptacom.net/pubblicazioni/pub_it/nl_8.html
    al punto d.
    Tuttavia se usi Visual C++ ti avviso che ha un bug riguardo i distruttori virtuali derivati tramite ereditarietà virtuale: non li richiama. Un bug che pare si porti dietro da VC6.
    A me è capitato in un paio di occasioni di dover rscrivere una classe, trasformando dei raw pointer in smart_pointer.

    Eventualmente posta il codice (o la parte interessata per vedere se si può risolvere in altro modo)
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    No essendo costretto ad utilizzare le librerie Qt sto usando Qt Creator.
    (Avevo avuto proprio un dubbio sui distruttori virtuali quando avevo cominciato ed avevo aperto una discussione su questo forum, alla fine si era scoperto che funzionavano a dovere)
    Ora purtroppo per un paio di giorni sono in giro (sto scrivendo dal tablet) e non ho accesso al mio pc. In ogni caso avevo già pensato di inserire il codice ma sono tantissime righe, esiste un modo in questo forum per allegare i file?
    Comunque grazie mile per le tue risposte, la tua pazienza e la dritta. Studierò il link che mi hai proposto

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.