2011-11-16 17 views
31

Właśnie utworzyłem hierarchię wyjątków i chciałem przekazać char* do konstruktora jednej z moich klas pochodnych z komunikatem informującym, co jest nie tak, ale najwyraźniej std::exception nie ma konstruktora, który pozwoliłby do tego. Istnieje jednak członek klasy o nazwie what(), który sugeruje, że niektóre informacje mogą zostać przekazane.
Jak mogę (mogę?) Przekazać tekst do klasy pochodnej z std::exception w celu przekazania informacji z mojej klasy wyjątków, więc mogę powiedzieć, gdzieś w kodzie:Poprawny sposób dziedziczenia ze std :: wyjątek

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

Wiem, że to nie odpowiada na twoje pytanie, ale możesz chcieć przeczytać [to] (http://www.codeproject.com/KB/cpp/cppexceptionsproetcontra.aspx) zanim zaczniesz używać wyjątków. Jest tu również wiele pytań na temat przepełnienia stosu, w którym wyjątki są dobre lub złe (odpowiedź jest głównie zła). – Shahbaz

Odpowiedz

38

Jeśli chcesz skorzystać Konstruktor łańcuchów powinien dziedziczyć po std::runtime_error lub std::logic_error, który implementuje konstruktor łańcuchów i implementuje metodę std :: exception :: what.

To jest tylko przypadek wywołania konstruktora runtime_error/logic_error z nowej odziedziczonej klasy, lub jeśli używasz C++ 11 możesz użyć dziedziczenia konstruktora.

4

Metoda what jest wirtualna, a znaczenie ma to, że należy ją przesłonić, aby zwrócić jakąś wiadomość, którą chcesz zwrócić.

+24

masz na myśli zastąpić? – smallB

+0

Brak przeciążenia ... – Hydro

5

Jak o tym:

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

Albo utworzyć konstruktor zaakceptowaniem opis, jeśli chcesz ...

+1

@ user472155 +1 za dobrą odpowiedź. Przy okazji jednak, myślę, że warto tutaj wspomnieć, że podpis podany w przykładzie dla jakiej funkcji, oznacza tylko kod przed C++ 11. –

44

używam następujące klasy dla moich wyjątki i to działa dobrze:

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

Skąd pochodzi słowo kluczowe "msg_"? Nie wiedziałem, że możesz nazwać wyciąg po ":" deklaracji metody. Myślę, że było to tylko dla klasy bazowej. – Nap

+1

msg_ jest ** chronionym ** członkiem wyjątku; jest instancją std :: string, więc ma dostęp do swojej funkcji członkowskiej .c_str (konwertuje na ciąg c). – MattMatt

+1

co z konstruktorem kopii? – isnullxbh

Powiązane problemy