C++ C++;异常设计模式

C++ C++;异常设计模式,c++,design-patterns,exception-handling,C++,Design Patterns,Exception Handling,我想将Win32错误(从GetLastError()返回的错误)封装在某种形式的异常类中。但是,我不希望只有一个Win32异常,而是希望能够有一个专门的异常,可以捕获常见错误,例如错误\访问\拒绝 例如,我有如下声明的类: class WindowsException : public std::exception { public: static WindowsException Create(DWORD lastError); //blah }; class ErrorA

我想将Win32错误(从GetLastError()返回的错误)封装在某种形式的异常类中。但是,我不希望只有一个Win32异常,而是希望能够有一个专门的异常,可以捕获常见错误,例如错误\访问\拒绝

例如,我有如下声明的类:

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.
}
捕手可能看起来像:

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 factory方法返回一个WindowsException,那么子类型(可能是ErrorAccessDeniedException)将被切分为基类型。也就是说,实例不能是多态的。我不想使用new'd指针,因为这样会迫使异常处理程序在完成时删除它

有人知道一个设计解决方案可以优雅地解决这个问题吗

账单3改变

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


这意味着,不要返回异常然后抛出它(正如您所观察到的那样,它将切片),而是让您的助手/工厂方法直接抛出它。

更多的异常处理背景阅读:

关于类型切片和重排序的注释:

当重新引发异常e时, 喜欢写作只是扔;相反 投掷e;因为第一种形式 始终保持 回收对象


您可以创建一个宏来声明几个不同的异常类型,并根据
GetLastError()
的值创建一个用于引发的工厂;但老实说,我只见过这样处理这个问题:该解决方案的问题是它不允许您创建特定的捕获处理程序——它是该类型所有异常的单一异常类型。您应该通过引用来捕获异常,而不是像上面的代码示例当前所示的那样通过值来捕获异常。。。DUH BILL:)非常感谢。当我阅读这个问题时,我发明了一个复杂的解决方案,其中框架维护了每个可能异常的静态实例。特里的解决方案只有在你看过之后才是“显而易见的”。(或者是这样,或者我们都很愚蠢:-)WindowsAPI::WindowsException::Throw()让该函数调用
GetLastError()
有什么问题吗?你可以--我在示例代码中使用了显式GetLastError()来更清楚地说明我想做什么。不是说这是错误信息,而是。。。这和我的问题有什么关系呢?只是通过异常处理提醒更多可能的切片问题。