2014-10-02 11 views
7

Come posso proteggermi dall'usare un oggetto che non è completamente creato quando si usano le eccezioni? Devo prendere in costruttore? O forse è una cattiva pratica? Se prenderò in oggetto costruttore verrà creato.C++ che intercetta l'eccezione nel costruttore

#include <stdio.h> 

class A 
{ 
public: 
    A() 
    { 
     try { 
      throw "Something bad happened..."; 
     } 
     catch(const char* e) { 
      printf("Handled exception: %s\n", s); 
     } 
     // code continues here so our bad/broken object is created then? 
    } 
    ~A() 
    { 
     printf("A:~A()"); 
    } 

    void Method() 
    { // do something 
    } 
}; 

void main() 
{ 
    A object; // constructor will throw... and catch, code continues after catch so basically we've got 
       // broken object. 

    //And the question here: 
    // 
    //* is it possible to check if this object exists without catching it from main? 
    // &object still gives me an address of this broken object so it's created but how can I protect myself 
    // from using this broken object without writing try/catch and using error codes? 
    object.Method(); // something really bad. (aborting the program) 

}; 
+0

Perché ponete restrizioni completamente arbitrarie su di voi? –

risposta

9

Il linguaggio stesso non ha il concetto di un oggetto che è "non valido" in alcun modo rilevabile.

Se l'eccezione indica che un oggetto valido non può essere creato, non deve essere gestito all'interno del costruttore; o riponetelo o non catturatelo in primo luogo. Quindi il programma lascerà l'ambito dell'oggetto creato e non sarà possibile accedervi in ​​modo errato.

Se questa non è un'opzione per qualche motivo, allora è necessario il proprio modo per contrassegnare l'oggetto come "non valido"; forse impostare una variabile membro booleano alla fine del costruttore per indicare il successo. Questo è traballante e soggetto a errori, quindi non farlo a meno che tu non abbia una buona ragione.

+0

Grazie, questo è quello che volevo sapere. – user3841735

2

Se l'oggetto si trova in uno stato non valido quando viene generata una certa eccezione, allora avrei lasciato l'eccezione rilassarsi lo stack di chiamate in modo che il chiamante può essere notificato (e quindi reagire) a queste cose.

Tuttavia, se l'eccezione è quella da cui è possibile eseguire il ripristino, potrebbe essere utile provare a farlo in base alla propria applicazione. Assicurati di utilizzare qualcosa come un logger o anche semplicemente stderr per indicare che questo sta accadendo però.

1

ho intenzione di proporre una prima iterazione di fare qualcosa di più simile a questo:

try { 
     throw "Something bad happened..."; 
    } 
    catch(const std::exception e) { 
     cerr << e.what() << endl ; // Better off in the main 
     throw ; 
    } 

Due cose qui:

  1. A meno che il gestore di eccezioni gestisce l'eccezione, si dovrebbe buttare.

  2. Utilizzare sempre le classi di eccezioni basate su std :: eccezione per che è sempre possibile scoprire quale fosse il problema come mostrato sopra.