По-настоящему приятнее было бы создать класс (или классы) для исключений.
Что-то вроде:
class ConfigurationError : public std::exception {
public:
ConfigurationError();
};
class ConfigurationLoadError : public ConfigurationError {
public:
ConfigurationLoadError(std::string & filename);
};
Причина в том, что исключения намного предпочтительнее, чем просто передача строки. Предоставляя различные классы для ошибок, вы даете разработчикам возможность обработать конкретную ошибку соответствующим образом (а не просто отображать сообщение об ошибке). Люди, перехватывающие ваше исключение, могут быть сколь угодно конкретными, если вы используете иерархию.
а) Возможно, потребуется знать конкретную причину
} catch (const ConfigurationLoadError & ex) {
// ...
} catch (const ConfigurationError & ex) {
а) другой не хочет знать подробностей
} catch (const std::exception & ex) {
Вдохновение по этой теме можно найти в https://books.google.ru/books?id=6tjfmnKhT24C. главе 9.
Кроме того , вы можете предоставить пользовательское сообщение тоже, но будьте осторожны - это не безопасно , чтобы составить сообщение с любым std::stringили std::stringstreamили любым другим способом , который может вызвать исключение .
Как правило, нет разницы, выделяете ли вы память (работаете со строками в стиле C ++) в конструкторе исключения или непосредственно перед выбросом - std::bad_alloc исключение может быть сгенерировано до того, которое вам действительно нужно.
Итак, буфер, выделенный в стеке (как в ответе Максима), является более безопасным способом.
Это очень хорошо объясняется на http://www.boost.org/community/error_handling.html.
Итак, более приятным способом было бы конкретный тип исключения и избегать составления отформатированной строки (по крайней мере, при выбросе).
std∷exceptionвас нет конструктора сchar*arg.