Как избежать помещения std :: string в класс исключения?

Вот мой класс исключения:

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(&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 ++ и, следовательно, не идеально решение.

Подходит ли это реализация класса исключения? Если нет, какие улучшения можно сделать?

8
задан void.pointer 22 February 2012 в 22:08
поделиться