C ++ Exception Design Pattern - PullRequest
       2

C ++ Exception Design Pattern

6 голосов
/ 11 января 2010

Я хотел бы инкапсулировать ошибки Win32 (возвращаемые из GetLastError ()) в некоторой форме класса исключений. Однако вместо того, чтобы иметь единственное исключение Win32, я хотел бы иметь возможность иметь специальное исключение, которое можно отследить для распространенных ошибок, например ERROR_ACCESS_DENIED.

Например, я бы объявил классы так:

class WindowsException : public std::exception
{
public:
    static WindowsException Create(DWORD lastError);
    //blah

};

class ErrorAccessDeniedException : public WindowsException
{
public:
    //blah
};

Однако я бы хотел, чтобы исключение Win32 отвечало за выбор правильного исключения для возврата. То есть метатель исключения должен выглядеть так:

int DangerousMethod() {
    throw WindowsAPI::WindowsException::Create(GetLastError());
}

и зрелище может выглядеть так:

try
{
    DangerousMethod();
} catch(WindowsAPI::ErrorAccessDeniedException ex)
{
    //Code for handling ERROR_ACCESS_DENIED
} catch(WindowsAPI::WindowsException ex)
{
    //Code for handling other kinds of error cases.
}

Моя проблема заключается в том, что если метод фабрики WindowsException :: Create возвращает исключение WindowsException, то подтип (потенциально ErrorAccessDeniedException) разделяется до базового типа. То есть экземпляр не может быть полиморфным. Я не хочу использовать указатель new'd, потому что это заставит обработчик исключений удалить его, когда это будет сделано.

Кто-нибудь знает проектное решение, которое было бы целесообразно для элегантного решения этой проблемы?

Billy3

Ответы [ 2 ]

12 голосов
/ 11 января 2010

Изменение

int DangerousMethod() {
    throw WindowsAPI::WindowsException::Create(GetLastError());
}

Для

int DangerousMethod() {
    WindowsAPI::WindowsException::Throw(GetLastError());
}

То есть вместо того, чтобы возвращать исключение, а затем выбрасывать его (что, как вы заметили, будет срезано), ваш вспомогательный / фабричный метод генерирует его напрямую.

2 голосов
/ 11 января 2010

Еще несколько фоновых чтений для обработки исключений: http://www.informit.com/articles/article.aspx?p=373339

Примечание по типу нарезки и повторного бросания:

При сбросе исключения e, предпочитаю писать просто бросить; вместо броска е; потому что первая форма всегда сохраняет полиморфизм переброшенный объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...