Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    137

    [C++] Polimorfismo. errore classe eccezioni

    Mi scuso per il precedente topic, avevo dato per scontato si parlasse di C++.
    Torno al mio problema.
    In fase di compilazione ho questi warning:

    codice:
    Dictionary_Exception.h:20: warning: 'class Dictionary_Exception' has virtual functions but non-virtual destructor
    Dictionary_Exception.h:27: warning: 'class EmptyError' has virtual functions but non-virtual destructor
    Dictionary.h: In instantiation of 'Dictionary<int, std::string>':
    RB_Tree.h:19:   instantiated from 'RB_Tree<int, std::string>'
    main.cpp:18:   instantiated from here
    Dictionary.h:15: warning: 'class Dictionary<int, std::string>' has virtual functions but non-virtual destructor
    RB_Tree.h: In instantiation of 'RB_Tree<int, std::string>':
    main.cpp:18:   instantiated from here
    RB_Tree.h:19: warning: 'class RB_Tree<int, std::string>' has virtual functions but non-virtual destructor
    Dictionary_Exception.h: In instantiation of 'SearchError<int>':
    RB_Tree.h:384:   instantiated from 'Data RB_Tree<Key, Data>::Search(Key) [with Key = int, Data = std::string]'
    main.cpp:39:   instantiated from here
    Dictionary_Exception.h:37: warning: 'class SearchError<int>' has virtual functions but non-virtual destructor
    Dictionary_Exception.h: In instantiation of 'RemoveError<int>':
    RB_Tree.h:428:   instantiated from 'void RB_Tree<Key, Data>::Remove(Key) [with Key = int, Data = std::string]'
    main.cpp:45:   instantiated from here
    Dictionary_Exception.h:50: warning: 'class RemoveError<int>' has virtual functions but non-virtual destructor

    Perchè dovrei fare un distruttore virtuale?
    questa la mia classe:

    codice:
    #ifndef DICTONARY_EXCEPTION_H_
    #define DICTONARY_EXCEPTION_H_ 1
    
    #include <iostream>
    
    //Classe che gestisce le eccezioni nel dizionario
    //Questa classe ha dei metodi in grado di rappresentare le eccezioni.
    //Il programma chiamato solleverà l'errore con throw, il chiamante intrappolerà
    //l'errore con catch.
    
    //Classe base di una eccezione
    class Dizionario_Exception
    {
    public:
    	   virtual void debug_print() const {std::cerr << "Dictionary Error" << std::endl; }
    };
    
    //Eccezioni di dizionario vuoto
    class EmptyError : public Dizionario_Exception
    {
    public:
    	   virtual void debug_print() const
    	   {
                std::cerr << "Dizionario vuoto."<<std::endl;
           }
    };
    
    //Eccezioni di ricerca (elemento non trovato)
    template <class Key> class SearchError : public Dizionario_Exception
    {
    private:
    	    Key k;
    public:
    	    SearchError(Key &key){k=key;}
        	virtual void debug_print() const
        	{
        		 std::cerr << "Ricerca fallita, l'elemento con chiave "<<k<<" non Ë stato trovato."<<std::endl;
        	}
    };
    
    //Eccezioni di cancellazione (elemento non trovato)
    template <class Key> class RemoveError : public Dizionario_Exception
    {
    private:
    	    Key k;
    public:
        	RemoveError(Key &key){k=key;}
        	virtual void debug_print() const
        	{
        		 std::cout << "Cancellazione non effettuata, l'elemento con chiave "<<k<<" non Ë presente nel dizionario"<<std::endl;
        	}
    };
    
    
    
    #endif /* DICTONARY_EXCEPTION_H_ */
    $Pippo... la variabile preferita dall'ingegnere!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Perché è buona norma farlo. Se una classe Base non definisce il distruttore virtual, non verranno richiamati i distruttori delle classi derivate ma solo quello della classe Base con tutte le conseguenze del caso.

    http://www.emagsoftware.it/faqcpp.htm#19
    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
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    137
    Originariamente inviato da shodan
    Perché è buona norma farlo. Se una classe Base non definisce il distruttore virtual, non verranno richiamati i distruttori delle classi derivate ma solo quello della classe Base con tutte le conseguenze del caso.

    http://www.emagsoftware.it/faqcpp.htm#19
    in questo specifico caso postato tu come faresti?
    Come faresti il distruttore o i distruttori?
    $Pippo... la variabile preferita dall'ingegnere!

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Basta mettere virtuale il distruttore della classe base per accontentare il compilatore.
    Nel caso specifico in esame il distruttore non deve effettuare un cleanup di risorse e nelle classi derivate può essere omesso.
    Però se una classe derivata fosse costituita così (ad esempio):
    codice:
    //Eccezioni di dizionario vuoto
    class EmptyError : public Dizionario_Exception
    {
    public:
           EmptyError() { dato_privato = new char[MAXLEN]; } 	   
           ~EmptyError() { delete[] dato_privato; }
           virtual void debug_print() const
    	   {
                std::cerr << "Dizionario vuoto."<<std::endl;
           }
    private:
         char* dato_privato.
    };
    Allora è imperativo che sia virtuale il distruttore della classe base o la memoria rimane allocata.
    Per evitare problemi futuri meglio mettere sempre i distruttori virtuali.
    E ricorda che il polimorfismo non funziona solo con i puntatori, ma anche con i reference.
    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
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    137
    infatti ho messo un distruttore virtuale vuoto (cioè che non distrugge nulla, essendoci solo una print e nessun dato membro) nella classe base e mi ha tolto tutti gli warning.
    Però sinceramente non mi sembra una pratica molto corretta fare un distruttore vuoto, non trovi?
    Nelle classi derivate a me basta che venga invocato quello di default.

    Inoltre visto che ho un'altra classe derivata RB_Tree col suo distruttore (è un albero binario, quindi stavolta mi serve che vengano cancellati tutti i puntatori) che eredita un'interfaccia con le operazioni consentite (quindi una classe Dictionary con solo metodi vituali), mi ridà lo stesso warning.
    Però mi rifiuto di inserire un distruttore nell'interfaccia.. che senso ha? Ci deve essere un'altra soluzione.. hai idea?
    $Pippo... la variabile preferita dall'ingegnere!

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Cosmy
    Però sinceramente non mi sembra una pratica molto corretta fare un distruttore vuoto, non trovi?
    No.

    Originariamente inviato da Cosmy
    Però mi rifiuto di inserire un distruttore nell'interfaccia.. che senso ha? Ci deve essere un'altra soluzione.. hai idea?
    Non ci sono altre soluzioni.
    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.

  7. #7
    Originariamente inviato da Cosmy
    Però sinceramente non mi sembra una pratica molto corretta fare un distruttore vuoto, non trovi?
    Se vuoi la certezza di innumerevoli disastrosi mal di testa futuri... allora non scriverne..

    se invece vuoi evitarli, costruisci SEMPRE distruttori virtuali (anche vuoti) per classi da cui prevedi di poter derivare altre classi.

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.