Naprawdę przyjemniejszym sposobem byłoby utworzenie klasy (lub klas) dla wyjątków.
Coś jak:
class ConfigurationError : public std::exception {
public:
ConfigurationError();
};
class ConfigurationLoadError : public ConfigurationError {
public:
ConfigurationLoadError(std::string & filename);
};
Powodem jest to, że wyjątki są znacznie lepsze niż zwykłe przesyłanie łańcucha. Zapewniając różne klasy dla błędów, dajesz programistom szansę na obsłużenie określonego błędu w odpowiedni sposób (a nie tylko wyświetlenie komunikatu o błędzie). Jeśli korzystasz z hierarchii, osoby wychwytujące Twój wyjątek mogą być tak szczegółowe, jak potrzebują.
a) Być może trzeba będzie znać konkretny powód
} catch (const ConfigurationLoadError & ex) {
// ...
} catch (const ConfigurationError & ex) {
a) inny nie chce znać szczegółów
} catch (const std::exception & ex) {
Inspirację na ten temat można znaleźć w https://books.google.ru/books?id=6tjfmnKhT24C Rozdział 9
Ponadto, można dostarczyć niestandardowy komunikat zbyt, ale należy zachować ostrożność - nie jest to bezpieczne, aby utworzyć wiadomość z albo std::string
albo std::stringstream
albo jakikolwiek inny sposób, który może spowodować wyjątek .
Generalnie nie ma różnicy, czy alokujesz pamięć (pracujesz z napisami w sposób C ++) w konstruktorze wyjątku, czy tuż przed wyrzuceniem - std::bad_alloc
wyjątek można wyrzucić przed tym, który naprawdę chcesz.
Tak więc bufor przydzielony na stosie (jak w odpowiedzi Maxima) jest bezpieczniejszym sposobem.
Jest to bardzo dobrze wyjaśnione na http://www.boost.org/community/error_handling.html
Więc lepszym sposobem byłby określony typ wyjątku i unikanie tworzenia sformatowanego ciągu (przynajmniej podczas rzucania).
std∷exception
nie masz konstruktora zchar*
arg.