Вот мой класс исключений:
class Win32Failure : public std::exception
{
public:
Win32Failure( char const* win32_function_name, LONG error_code );
char const* win32_function_name() const { return win32_function_name_; }
LONG error_code() const { return error_code_; }
virtual char const* what() const;
private:
std::string GetFormattedMessage() const;
char const* win32_function_name_;
LONG error_code_;
std::string error_text_;
};
Win32Failure::Win32Failure( char const* win32_function_name, LONG error_code )
: error_code_(error_code)
, win32_function_name_(win32_function_name)
{
std::stringstream error_msg;
error_msg << win32_function_name << " failed with code: "
<< error_code << " (" << GetFormattedMessage() << ")"
;
error_text_ = error_msg.str();
}
std::string Win32Failure::GetFormattedMessage() const
{
TCHAR message_buffer[1000];
FormatMessage(
//FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error_code_,
0, // Default language
reinterpret_cast<LPTSTR>(&message_buffer),
sizeof(message_buffer) / sizeof(TCHAR),
NULL
);
return std::string(message_buffer);
}
char const* Win32Failure::what() const
{
return error_text_.c_str();
}
рекомендации по повышению исключений рекомендуют не размещать какие-либо объекты, которые выделяют память, как члены моего класса исключений.В этом случае использование std::string
нарушает это.Я уважаю правило для этого, однако я не могу придумать способ реализовать переопределение what()
без использования std :: string для управления памятью (вместо того, чтобы требовать, чтобы вызывающий управлял для меня).
Я мог бы использовать буфер фиксированного размера в качестве члена и использовать функции библиотеки C (например, snprintf()
) для выполнения этой работы, но это не очень идиоматично для C ++ и, следовательно, не является идеальным решением.
Это подходящая реализация класса исключения?Если нет, какие улучшения могут быть сделаны?