Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Exception Design Pattern

I'd like to encapsulate Win32 errors (those returned from GetLastError()) in some form of exception class. Rather than having a single Win32 exception, however, I'd like to be able to have a specialized exception catchable for common errors, such as ERROR_ACCESS_DENIED.

For example, I'd have classes declared like this:

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

};

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

However, I'd like the Win32 exception to be responsible for picking the right exception to return. That is, the thrower of the exception should look like:

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

and the catcher might look like:

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

My problem is that if the WindowsException::Create factory method returns a WindowsException, then the subtype (potentially ErrorAccessDeniedException) is sliced down to the base type. That is, the instance can't be polymorphic. I don't want to use a new'd pointer, because that would force the exception handler to delete it when it's done.

Does anyone know of a design solution that would be feasible for solving this problem elegantly?

Billy3

like image 970
Billy ONeal Avatar asked Jan 11 '10 01:01

Billy ONeal


1 Answers

Change

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

To

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

Meaning, instead of returning the exception then throwing it (which will slice, as you observed), have your helper/factory method throw it directly.

like image 176
Terry Mahaffey Avatar answered Sep 19 '22 07:09

Terry Mahaffey