Дійсно приємнішим способом було б створення класу (або класів) для винятків.
Щось на зразок:
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*
аргументом.