2011-11-16 17 views
31

Ho appena creato la gerarchia delle eccezioni e volevo passare char* al costruttore di una delle mie classi derivate con un messaggio che diceva cosa non va, ma apparentemente std::exception non ha il costruttore che consentirebbe io per farlo. Eppure c'è un membro della classe chiamato what() che suggerirebbe che alcune informazioni possano essere passate.
Come posso (posso?) Passare il testo alla classe derivata di un std::exception per passare informazioni con la mia classe di eccezione, quindi posso dire che da qualche parte nel codice:Modo corretto per ereditare da std :: exception

throw My_Exception("Something bad happened."); 
+0

So che questo non risponde alla tua domanda, ma potresti voler leggere [questo] (http://www.codeproject.com/KB/cpp/cppexceptionsproetcontra.aspx) prima di iniziare ad usare le eccezioni. Ci sono anche molte domande qui sullo stack overflow sulle eccezioni che sono buone o cattive (la risposta è per lo più cattiva). – Shahbaz

risposta

38

Se si desidera utilizzare del costruttore di stringhe, si dovrebbe ereditare da std::runtime_error o std::logic_error che implementa un costruttore di stringhe e implementa il metodo std :: exception :: what.

Quindi è solo un caso di chiamare il costruttore runtime_error/logic_error dalla nuova classe ereditata, oppure se si utilizza C++ 11 è possibile utilizzare l'ereditarietà del costruttore.

4

Il metodo what è virtuale e il significato è che è necessario sovrascriverlo per restituire qualsiasi messaggio che si desidera restituire.

+24

vuoi dire override? – smallB

+0

Nessun sovraccarico ... – Hydro

5

ne dite di questo:

class My_Exception : public std::exception 
{ 
public: 
virtual char const * what() const { return "Something bad happend."; } 
}; 

Oppure, creare un costruttore di accettare la descrizione se vuoi ...

+1

@ user472155 +1 per la buona risposta. Comunque, penso che valga la pena menzionare qui, che la firma che hai fornito nel tuo esempio per la funzione what, implica solo il codice prima di C++ 11. –

44

Io uso la seguente classe per le mie eccezioni e funziona benissimo:

class Exception: public std::exception 
{ 
public: 
    /** Constructor (C strings). 
    * @param message C-style string error message. 
    *     The string contents are copied upon construction. 
    *     Hence, responsibility for deleting the char* lies 
    *     with the caller. 
    */ 
    explicit Exception(const char* message): 
     msg_(message) 
     { 
     } 

    /** Constructor (C++ STL strings). 
    * @param message The error message. 
    */ 
    explicit Exception(const std::string& message): 
     msg_(message) 
     {} 

    /** Destructor. 
    * Virtual to allow for subclassing. 
    */ 
    virtual ~Exception() throw(){} 

    /** Returns a pointer to the (constant) error description. 
    * @return A pointer to a const char*. The underlying memory 
    *   is in posession of the Exception object. Callers must 
    *   not attempt to free the memory. 
    */ 
    virtual const char* what() const throw(){ 
     return msg_.c_str(); 
    } 

protected: 
    /** Error message. 
    */ 
    std::string msg_; 
}; 
+0

da dove proviene la parola chiave "msg_"? Non sapevo che si potesse chiamare una dichiarazione dopo ":" di una dichiarazione di metodo. Penso che fosse solo per la classe base. – Nap

+1

msg_ è un membro ** protetto ** di Eccezione; è un'istanza di std :: string, quindi ha accesso alla funzione membro .c_str (converte in stringa c). – MattMatt

+1

E il costruttore di copie? – isnullxbh

Problemi correlati