Один вариант, если количество функций ограничено, было бы использовать шаблон функции:
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();
}
Это предполагает, что handleException
является некоторой функцией, не являющейся членом, но это легкоизменить его, если это функция-член.Вам нужно решить, что call_and_handle
возвращает, если обработано исключение;У меня он возвращает инициализированный ReturnT
в качестве заполнителя.
Это сокращает ваши функции-члены до:
int myClass::abstract_one()
{
return call_and_handle(_original, &myClass::abstract_one);
}
Вам потребуется отдельный шаблон функции для вызова функций, которые имеют один параметр,два параметра и т. д.
Если у вас есть функции с громоздким числом параметров и вы действительно впали в отчаяние, вы могли бы использовать макрос (хотя я бы не рекомендовал это):
#define CALL_AND_HANDLE(expr) \
try { \
return (expr); \
} \
catch (const std::exception& ex) { \
handleException(ex); \
} \
catch (...) { \
handleException(); \
}
Что можно использовать как:
int myClass::abstract_one()
{
CALL_AND_HANDLE(_original->myClass::abstract_one());
}
В качестве отступления, если вы catch (...)
и не выбрасываете перехваченное исключение, вам в большинстве случаев следует прекратить программу.