Un modo davvero più carino sarebbe creare una o più classi per le eccezioni.
Qualcosa di simile a:
class ConfigurationError : public std::exception {
public:
ConfigurationError();
};
class ConfigurationLoadError : public ConfigurationError {
public:
ConfigurationLoadError(std::string & filename);
};
Il motivo è che le eccezioni sono molto più preferibili del semplice trasferimento di una stringa. Fornendo classi diverse per gli errori, dai agli sviluppatori la possibilità di gestire un errore particolare in modo corrispondente (non solo visualizzare un messaggio di errore). Le persone che rilevano la tua eccezione possono essere specifiche quanto necessitano se utilizzi una gerarchia.
a) Potrebbe essere necessario conoscere il motivo specifico
} catch (const ConfigurationLoadError & ex) {
// ...
} catch (const ConfigurationError & ex) {
a) un altro non vuole conoscere i dettagli
} catch (const std::exception & ex) {
Puoi trovare ispirazione su questo argomento in https://books.google.ru/books?id=6tjfmnKhT24C Capitolo 9
Inoltre, puoi fornire anche un messaggio personalizzato, ma fai attenzione: non è sicuro comporre un messaggio con std::stringo std::stringstreamo in qualsiasi altro modo che possa causare un'eccezione .
In generale, non c'è differenza se si alloca memoria (si lavora con le stringhe in modo C ++) nel costruttore dell'eccezione o appena prima di lanciare - l' std::bad_alloceccezione può essere lanciata prima di quella che si vuole veramente.
Quindi, un buffer allocato nello stack (come nella risposta di Maxim) è un modo più sicuro.
È spiegato molto bene su http://www.boost.org/community/error_handling.html
Quindi, il modo migliore sarebbe un tipo specifico di eccezione ed evitare di comporre la stringa formattata (almeno durante il lancio).
std∷exceptionnon hai un costruttore conchar*arg.