Wil*_*mKF 22 c++ refactoring templates exception
我有一个模式,重复几个成员函数,如下所示:
int myClass::abstract_one(int sig1)
{
try {
return _original->abstract_one(sig1);
} catch (std::exception& err) {
handleException(err);
} catch (...) {
handleException();
}
}
bool myClass::abstract_two(int sig2)
{
try {
return _original->abstract_two(sig2);
} catch (std::exception& err) {
handleException(err);
} catch (...) {
handleException();
}
}
[...]
int myClass::abstract_n(bool sig3a, short sig3b)
{
try {
return _original->abstract_n(sig3a, sig3b);
} catch (std::exception& err) {
handleException(err);
} catch (...) {
handleException();
}
}
Run Code Online (Sandbox Code Playgroud)
其中抽象一个到n是纯虚拟抽象接口用于其的方法myClass
和_original
是具体实现.
我不喜欢这个模式在代码中重复,并希望找到一种方法来消除重复try
/ catch
模式和代码作为单个抽象,但我想不出一个在没有宏的情况下在C++中执行此操作的好方法.我认为有一种方法可以让模板更好地完成这项工作.
请建议一种简洁的方法来重构此代码以抽象出重复的模式.
Ale*_*ler 24
我问了一个非常相似的概念问题,看看在嵌套的"尝试"中重新抛出异常合法吗?.
基本上,您可以通过捕获所有异常,调用处理程序并重新抛出活动异常,将各种异常处理程序移动到单独的函数.
void handle() {
try {
throw;
} catch (std::exception& err) {
handleException(err);
} catch (MyException& err) {
handleMyException(err);
} catch (...) {
handleException();
}
}
try {
return _original->abstract_two(sig2);
} catch (...) {
handle();
}
Run Code Online (Sandbox Code Playgroud)
它可以很好地扩展到更多不同的异常类型以进行区分.try .. catch(...)
如果您愿意,可以将第一个包装到宏中:
BEGIN_CATCH_HANDLER
return _original->abstract_two(sig2);
END_CATCH_HANDLER
Run Code Online (Sandbox Code Playgroud)
Jam*_*lis 15
如果函数arities数量有限,一个选项是使用函数模板:
template <typename ReturnT, typename ClassT>
ReturnT call_and_handle(ClassT* obj, ReturnT(ClassT::*func)())
{
try {
return (obj->*func)();
}
catch (const std::exception& ex) {
handleException(ex);
}
catch (...) {
handleException();
}
return ReturnT();
}
Run Code Online (Sandbox Code Playgroud)
这假设handleException
是一些非成员函数,但如果它是成员函数,则很容易修改它.call_and_handle
如果处理异常,您需要决定返回什么; 我让它返回初始化ReturnT
为占位符.
这会将您的成员函数减少为:
int myClass::abstract_one()
{
return call_and_handle(_original, &myClass::abstract_one);
}
Run Code Online (Sandbox Code Playgroud)
您需要一个单独的函数模板来调用具有一个参数,两个参数等的函数.
如果你的函数具有大量的参数并且你真的很绝望,你可以使用一个宏(我不会真的推荐这个):
#define CALL_AND_HANDLE(expr) \
try { \
return (expr); \
} \
catch (const std::exception& ex) { \
handleException(ex); \
} \
catch (...) { \
handleException(); \
}
Run Code Online (Sandbox Code Playgroud)
哪个可以用作:
int myClass::abstract_one()
{
CALL_AND_HANDLE(_original->myClass::abstract_one());
}
Run Code Online (Sandbox Code Playgroud)
catch (...)
顺便说一句,如果你不重新抛出被捕获的异常,你应该在大多数情况下终止该程序.
归档时间: |
|
查看次数: |
6317 次 |
最近记录: |