Uma maneira realmente melhor seria criar uma classe (ou classes) para as exceções.
Algo como:
class ConfigurationError : public std::exception {
public:
ConfigurationError();
};
class ConfigurationLoadError : public ConfigurationError {
public:
ConfigurationLoadError(std::string & filename);
};
O motivo é que as exceções são muito mais preferíveis do que apenas transferir uma string. Fornecendo classes diferentes para os erros, você dá aos desenvolvedores a chance de lidar com um erro específico de uma forma correspondente (não apenas exibir uma mensagem de erro). As pessoas que detectam sua exceção podem ser tão específicas quanto precisam se você usar uma hierarquia.
a) Pode ser necessário saber o motivo específico
} catch (const ConfigurationLoadError & ex) {
// ...
} catch (const ConfigurationError & ex) {
a) outro não quer saber detalhes
} catch (const std::exception & ex) {
Você pode encontrar inspiração neste tópico no https://books.google.ru/books?id=6tjfmnKhT24C Capítulo 9
Além disso, você pode fornecer uma mensagem personalizada também, mas tenha cuidado - não é seguro para compor uma mensagem com qualquer um std::string
ou std::stringstream
ou qualquer outra forma que pode causar uma exceção .
Geralmente, não há diferença se você aloca memória (trabalha com strings no modo C ++) no construtor da exceção ou imediatamente antes de lançar - a std::bad_alloc
exceção pode ser lançada antes daquela que você realmente deseja.
Portanto, um buffer alocado na pilha (como na resposta de Maxim) é uma maneira mais segura.
É muito bem explicado em http://www.boost.org/community/error_handling.html
Então, a maneira mais legal seria um tipo específico de exceção e evitar a composição da string formatada (pelo menos ao lançar).
std∷exception
não tem um construtor comchar*
arg.