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

    [c++] come uscire dal flusso nel costruttore

    Ciao ho il costruttore della mia classe che fa delle operazioni, se alcune di queste operazioni non vanno a buon fine non sussitono
    le precondizioni per eseguire il restante flusso, come faccio ad uscire dal costruttore quando si verifica ciò?
    Mi trovo in difficoltà perchè se fossi stato in una normale funzione avrei semplicemente eseguito un return false, ma qui non posso
    far ritornare niente.
    Grazie

  2. #2
    Utente di HTML.it L'avatar di Ed_Bunker
    Registrato dal
    Jul 2003
    Messaggi
    1,119
    Ehm... a dire il vero dovrebbero essere i metodi a fare eventuali controlli sulle caratteristiche dell'oggetto precedentemente istanziato.
    Nel costruttore l'oggetto viene appunto creato per cui non c'e' proprio la necessita' di avere delle precondizioni (Che infatti MAI vengono indicate in un costruttore bensi' "solo" nei metodi ai quali quel tipo di oggetto ha "accesso").
    In un costruttore non "devono" essere effettuate delle operazioni ma soltanto delle inizializzazioni che servono ad impostare una o piu' proprieta' dell'oggetto da creare.

  3. #3
    Originariamente inviato da Ed_Bunker
    In un costruttore non "devono" essere effettuate delle operazioni ma soltanto delle inizializzazioni che servono ad impostare una o piu' proprieta' dell'oggetto da creare.
    Be', le inizializzazioni spesso implicano anche delle operazioni complesse e che possono non andare a buon fine; se si riscontrano problemi in un costruttore, comunque, di solito si solleva un'eccezione.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    46
    richiamare il distruttore?

  5. #5
    Che io sappia il distruttore non può essere richiamato direttamente, e comunque non risolverebbe il problema: l'oggetto sarebbe comunque creato.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Fai come dice MItaly, solleva una bella eccezione.

    esempio
    codice:
    class Eccezione { };
    class A {
    public:
    	A(int x) {
    		if (x<0) throw Eccezione;
    		// ...
    	}
    	/..
    };
    
    //da qualche parte:
    try {
    	A a(-23);
    } catch (Eccezione) {
    	//cosa fare se viene sollevata l'eccezione
    }
    GreyFox (Linux registered user #435102)
    greyfox.imente.org - GreyFox's shots (photo gallery)
    $ cd /pub
    $ more beer

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    La cosa migliore è catturare l'eccezione nel costruttore e settare un flag.

    codice:
    class A {
       public: 
           A() : p(0), k(0) {
               p = new int;  // questo funge
    
               k = new int;  // questo solleva una bad_alloc
    
           }
    
           ~A() {
               delete p;
               delete k;
           }
    
        private:
            int* p;
            int* k;
    
    };
    se l'eccezione non viene catturata nel costruttore, nessuno libera la memoria di p. In più l'esecuzione si arresta al momento dell'eccezione e l'oggetto rimane incompleto e il distruttore non è invocato.

    Un modo un pò laborioso è il seguente.
    codice:
    class A {
       public: 
           A() : p(0), k(0),init_ok(false) {
               try {
                   p = new int;  // questo funge
               } catch (std::bad_alloc& err) {
                   p=0;
                   init_ok = false;
               }
    
               try {
                   k = new int;  // questo solleva una bad_alloc
               } catch (std::bad_alloc& err) {
                  k=0; 
                  init_ok = false;
               }
               init_ok = true;
           }
    
           ~A() {
               delete p;
               delete k;
           }
           bool ok() const { return init_ok;}
        private:
            int* p;
            int* k;
            bool init_ok;
    };
    In questo caso l'eccezione è catturata e si setta il flag per poi controllarlo in un punto esterno del codice. (Ed eventualmente lanciare una successiva eccezione).
    Questo garantisce che il distruttore venga richiamato sempre.

  8. #8
    Utente di HTML.it L'avatar di Ed_Bunker
    Registrato dal
    Jul 2003
    Messaggi
    1,119
    Originariamente inviato da MItaly
    Be', le inizializzazioni spesso implicano anche delle operazioni complesse e che possono non andare a buon fine; se si riscontrano problemi in un costruttore, comunque, di solito si solleva un'eccezione.
    In un costruttore non dovrebbero essere previste "operazioni complesse" (E bisognerebbe capire cosa si intenda per complessita'".

    Se poi si ipotizza che qualcosa possa andar storto durante la creazione dell'oggetto allora bata prevedere una proprieta' che stia ad indicare proprio se tutto e' andato bene.

    Basterebbe ad esempo un flag che tramite un 'getter' restituisca, quando invocato su una determinata istanza, lo "stato" dell'istanza stessa.

    Imho e' un modo molto piu' "chiaro e pulito" di approcciare il problema.

  9. #9
    grazie per le delucidazioni, il mio costruttore deve fare molte operazioni e quindi ho spostato il tutto in funzioni esterne private e ho lasciato al costruttore il solo compito di inzializzazione degli attributi.
    thx

  10. #10
    Utente di HTML.it L'avatar di Ed_Bunker
    Registrato dal
    Jul 2003
    Messaggi
    1,119
    Originariamente inviato da mlipreri
    grazie per le delucidazioni, il mio costruttore deve fare molte operazioni e quindi ho spostato il tutto in funzioni esterne private e ho lasciato al costruttore il solo compito di inzializzazione degli attributi.
    thx

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.