2010-01-11 105 views
6

我想封装Win32错误(从GetLastError()返回)以某种形式的异常类。但是,我不希望只有一个Win32异常,而是希望能够获得可用于常见错误的特殊异常,如ERROR_ACCESS_DENIED。C++异常设计模式

例如,我不得不声明如下类别:

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 ::创建工厂方法返回一个WindowsException,然后子类型(潜在的ErrorAccessDeniedException)被分割为基本类型。也就是说,该实例不能是多态的。我不想使用new'd指针,因为这会强制异常处理程序在完成时删除它。

有谁知道可以优雅地解决这个问题的设计解决方案吗?

Billy3

+0

您可以创建一个宏来声明几个不同的异常类型,并根据'GetLastError()'的值创建一个抛出工厂。但说实话,我只见过这样的问题:http://code.google.com/p/synergy-plus/source/browse/trunk/lib/arch/XArchWindows.cpp – 2010-01-11 02:08:35

+0

问题与该解决方案是它不允许您创建特定的catch处理程序 - 对于该类型的所有异常,这是一种单一的异常类型。 – 2010-01-11 02:23:55

+1

你应该通过参考的方式来捕捉你的例外,而不是像上面的代码示例所显示的那样通过价值 – 2010-01-11 07:55:31

回答

12

变化

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

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

含义,而不是返回异常,然后把它扔(这将切片,当你观察到的),有你的帮手/工厂方法直接抛出。

+1

... DUH BILL :)非常感谢。 – 2010-01-11 02:09:07

+2

当我读到这个问题时,我发明了一个复杂的解决方案,其中每个可能的异常的静态实例都由框架维护。一旦你看到它,Terry的解决方案只是“DUH明显”。 (或者,或者我们都是愚蠢的:-) – 2010-01-11 02:21:49

+1

WindowsAPI :: WindowsException :: Throw()是什么问题,并让该函数调用GetLastError()? – sbi 2010-01-11 12:13:18

2

一些更多的异常处理的背景阅读:http://www.informit.com/articles/article.aspx?p=373339

的类型切片和重新抛出的说明:

当重新抛出异常E, 宁愿写随便扔;而不是 的投掷e;因为第一种形式 总是保留 重新排列的对象的多态性。

+2

不是说这是不好的信息,但是......这与我的问题有什么关系? – 2010-01-11 02:20:58

+0

只是警告更多可能的异常处理切片问题。 – 2010-01-11 04:24:38