gpt4 book ai didi

C++:如何处理从 std:exception 派生的异常,具体取决于它们的类型?

转载 作者:行者123 更新时间:2023-11-30 04:27:16 25 4
gpt4 key购买 nike

我想创建一个异常层次结构。我使用了 C++ 惯用法“多态异常”。

困难的一点是我希望这些类派生自 std::exception - 以便能够在代码的任何位置使用 try ... catch(exception &e) 捕获任何异常。

但是,无论异常来自 std::exception 还是来 self 的用户定义的异常,我都想以不同的方式处理异常。

这建议使用多态性,但是我不能在 std::exception 上定义虚函数。

我也试过使用函数模板(见下面的代码),但它不起作用,因为调用的模板函数是在编译时确定的。

#include <iostream>
#include <string>
using namespace std;

#include <boost\type_traits\is_base_of.hpp>
#include <boost\utility\enable_if.hpp>


class BaseError :public exception {
public:
virtual void raise(){throw *this;}
virtual string msg (){ return "This is the base class"; }
};

class DerivedError: public BaseError {
public:
void raise(){throw *this;}
string msg (){ return "This is the derived class"; }
};

template <typename T>
typename boost::disable_if<boost::is_base_of<BaseError, T>>::type
handleException(T &e)
{
cout << "Handling generic exception" << endl;
cout << e.what() << endl;
}
template <typename T>
typename boost::enable_if<boost::is_base_of<BaseError, T>>::type
handleException(T &e)
{
cout << "Handling specific exception" << endl;
cout << e.msg() << endl;
}


int main () {
BaseError b;
handleException(b);
// prints "Handling specific exception"
// prints "This is the base class"
try{
throw exception("Exception !!!");
}
catch (exception &e){
handleException(e);
// prints "Handling generic exception"
// prints "Exception !!!"
}
try{
BaseError b;
b.raise();
}
catch (exception &e){
handleException(e);
// prints "Handling generic exception" - I would like the specific behaviour
// prints "Unknown exception"
}
try{
DerivedError d;
d.raise();
}
catch (exception &e)
{
handleException(e);
// prints "Handling generic exception" - I would like the specific behaviour
// prints "Unknown exception"
}
return 0;
}

知道如何实现这一点吗?

提前致谢!

最佳答案

你可以在任何时候重新抛出异常,如果它发生在捕获之间,它将被定义。例如:

try
{
// something that throws an exception
} catch(std::exception& e) {
try
{
throw; // rethrows the original exception
} catch(std::runtime_error& e) {
// handle runtime error
} catch(std::exception& e) {
// handle everything else
}
}

现在嵌套的 try-catch block 可以在任何地方,它可以是一个函数甚至是一个对象析构函数。您可以组合一组处理特定异常的对象,将它们链接在一起并在链的末尾调用 throw;。伪代码:

template< typename E, typename Base = void >
struct exception_handler : Base
{
void handle() const
{
try
{
Base::handle();
} catch( E& e ) {
// do something
}
}
};

template< typename E >
struct exception_handler< E, void >
{
void handle() const
{
try
{
throw;
} catch( E& e ) {
// do something
}
}
};

那么上面的例子可以这样解释:

try
{
// something that throws an exception
} catch(std::exception& e) {
exception_handler<
std::exception
, exception_handler<
std::runtime_error
>
> handler;
handler.handle();
}

可以使用继承和常规类手动创建相同的层次结构,您可以在其中定义每个异常级别以及如何处理它们。

struct runtime_error_handler : base_handler
{
void handle() const
{
try
{
throw;
} catch( std::runtime_error& e ) {
// if the original exception was a runtime_error it will be caught here
// otherwise it will be propagated up the stack to exception_handler

// do something if runtime_error
}
}
};

struct exception_handler : runtime_error_handler
{
void handle() const
{
try
{
runtime_error_handler::handle();
} catch(std::exception& e) {
// do something else in the general case
}
}
};

关于C++:如何处理从 std:exception 派生的异常,具体取决于它们的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11067574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com