Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    [c++] Aiuto: gestire le eccezioni con <stdexception>

    Salve, sto scrivendo una classe template per uno stack e all'interno della funzione pop faccio uso di di una throw out_of_range della libreria stdexceptio.
    Io non sono ancora molto pratico è vorrei sapere come faccio a gestire l'eccezzione nel main. Spero ci sia qualcuno che mi può dare una mano, grazie.

    Il codice del metodo è:
    codice:
    template <class T>
    T stack<T>::pop(){
        if (size==0) throw std::out_of_range("Pila vuota");; 
        testa=(testa)->next;
        dat=testa->dato;
        size--;
        return dat;
    };
    Mentre nel main vorrei gestire l'eccezione causata dallo stack vuoto, stampando a video "Pila vuota". Come faccio a recuperare la stringa di throw std:ut_of_range?
    codice:
    int main(){
         int i;
         stack<int>* a=new stack<int>;
         try {i=a->pop();}
         catch (std::out_of_range &) {
            //qui vorrei stampare la stringa che si trova in pop out_of_range ???
        }
         return 0;
    }

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

    Re: [c++] Aiuto: gestire le eccezioni con <stdexception>

    Originariamente inviato da dunix87
    codice:
    int main(){
         int i;
         stack<int>* a=new stack<int>;
         try {
              i=a->pop();
         } catch (std::out_of_range& err)  {
            cerr << err.what() << endl; 
        }
         return 0;
    }
    Ricorda di deallocare "stack<int>* a" alla fine.

  3. #3
    Ah grazie mille, si è rivelato più semplice di quanto immagginavo.

    A questo punto avrei un altro dubbio a rigurado le eccezioni. Se ad esempio non sapessi a priori che l'eccezzione generata dalla funzione pop fosse di tipo out_of_range, esiste la possibilità di eseguire una catch su eccezione generica? O dovrei implementarlo in un altor modo rispetto al precedente? Sono ancora un po' confuso su quest'argomento...

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Dovrebbe bastare inserire un

    catch (...)

    per acchiappare ogni tipo di eccezione. Ovviamente non si può sapere quale.

    Puoi mettere anche più catch in cascata nel main.

    Codice PHP:

    try {
     ...
    } catch (
    std::out_of_rangeerr) {
      ...
    } catch (
    std::bad_allocerr) {
      ...
    } catch (
    std::runtime_errorerr) {
      ...
    } catch (...) {


  5. #5
    Ok grazie di nuovo, ovviamente nel caso ci catch(...) non potrei ottenere la stringa di errore, giusto?

    Se invece utilizzassi come identificatore la classe che contiene le eccezioni che io utilizzo, in questo logic_error, cioè:

    codice:
    catch (std::logic_error &err) {
            cout << err.what() << endl; 
        }
    Funzionerebbe ancora o andrei incontro ad errori inaspettati in condizioni particolari?
    Perchè facendo una prova rapida a rigore sembra funzionante

  6. #6
    std:ut_of_range è o non è derivata (direttamente o no) da std::exception?
    Quindi cattura solo (nell'ordine) "const std::exception &" e "..."!
    Altrimenti l'astrazione (e tutto il paradigma della programmazione ad oggetti) a che serve?
    ;-)

  7. #7
    ah... ok grazie...
    Non riuscivo bene a capire la struttura della libreria in effetti con std::exception &... le richiama tutte senza la necessità di ulteriori generalizzazioni.

    Forse dovrei aprire un altro post per questo, ho cambiare il titolo della discussione visto ke avrei bisogno di qualke altro kiarimento in merito alla classe stack ke sto costruendo.

    Vi posto i quesiti intanto:
    Non essendo ancora molto pratico mi rimangono vari dubbi.
    1)Ho notato che si può dichiare un oggetto di una classe come classe nome_oggetto
    oppure come classe* nome_oggetto=new classe.
    Vi posto il mio esempio per spiegarmi meglio.
    codice:
    int main(){
         int t;
         stack<int> a;
         stack<int>* b=new stack<int>;
         a.push(5);
         b->push(5);
         t=a.pop();
         t=b->pop();
         delete &a;
         delete b;
         system("PAUSE");
         return 0;
    }
    Che differenze ce fra l'oggetto a e quello b, oltre che il secondo è un puntatore? Quale fra i due è preferibile usare?

    2)Inoltre scrivendo la classe mi è sorto un altro dubbio, data anche la mia ancora scarsa affinità col linguaggio, cioè se io uso come parametro di un metodo della mia classe un oggetto della stessa classe, in teoria dovrei avere accesso dal metodo agli attributi privati dell'oggetto, o mi sbaglio?

    Vi ringrazio dell'aiuto fin qui fornitomi e spero di essere stato chiaro, inoltre chiedo scusa se ho sbagliato a postare questo messaggio.

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non essendo ancora molto pratico mi rimangono vari dubbi.
    1)Ho notato che si può dichiare un oggetto di una classe come classe nome_oggetto
    oppure come classe* nome_oggetto=new classe.
    Vi posto il mio esempio per spiegarmi meglio.
    codice:
    int main(){
         int t;
         stack<int> a;
         stack<int>* b=new stack<int>;
         a.push(5);
         b->push(5);
         t=a.pop();
         t=b->pop();
         delete &a;
         delete b;
         system("PAUSE");
         return 0;
    }
    Che differenze ce fra l'oggetto a e quello b, oltre che il secondo è un puntatore? Quale fra i due è preferibile usare?
    L'oggetto a è costruito sullo stack della funzione e pertanto viene distrutto quando termina il main; da ciò deriva che delete &a è male (infatti non fai delete &t).
    Nel secondo caso l'oggetto new stack<int> è costruito sull'heap e collegato tramite il puntatore b e alla fine va giustamente deallocato.
    Qui sorge un problema se viene sollevata un'eccezione non gestita: l'istruzione delete b non verrà mai invocata (in casi simili si utilizzano puntatori furbi) e il programma termina immediatamente.


    cioè se io uso come parametro di un metodo della mia classe un oggetto della stessa classe, in teoria dovrei avere accesso dal metodo agli attributi privati dell'oggetto, o mi sbaglio?
    Certo. Altrimenti costruttori di copia e operatori di assegnamento non si potrebbero fare.

  9. #9
    L'oggetto a è costruito sullo stack della funzione e pertanto viene distrutto quando termina il main; da ciò deriva che delete &a è male (infatti non fai delete &t).
    Nel secondo caso l'oggetto new stack<int> è costruito sull'heap e collegato tramite il puntatore b e alla fine va giustamente deallocato.
    Qui sorge un problema se viene sollevata un'eccezione non gestita: l'istruzione delete b non verrà mai invocata (in casi simili si utilizzano puntatori furbi) e il programma termina immediatamente.
    quindi da un certo punto di vista è meglio utilizzare il costrutto: classe oggetto almeno non corro il rischio di riempire l'heap in caso di eccezione imprevista oppure sarò costretto a preventivare tutte le eccezioni.

    Cosa intendi per puntatori furbi?

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Sono classi che si utilizzano come puntatori.
    Quello che la libreria del C++ mette a disposizione è std::auto_ptr (ma ce ne sono di migliori ad esempio nella libreria boost).

    Un esempio veloce (prendo spunto dal tuo codice)

    Codice PHP:

    #include <memory>

    int main() {
       
       
    std::auto_ptr<stack<int> > ptr(new stack<int>);
       
    ptr->pop(); // eccezione

    (nota lo stacco delle due > >, altrimenti il compilatore lo interpreta come >>)
    L'eccezione non è gestita, ma il distruttore di auto_ptr è invocato comunque e libera la memoria.
    Comodo quando non si riesce a prevedere il flusso del programma. (Ad esempio a causa di un uso massiccio delle eccezioni)

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 © 2025 vBulletin Solutions, Inc. All rights reserved.