重用C ++中的异常处理代码 [英] Reusing exception handling code in C++

查看:45
本文介绍了重用C ++中的异常处理代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有这两个功能,具有重复的异常处理,其唯一目的是显示错误消息:

I have these two functions, with duplicated exception treatment, which has the sole purpose of displaying an error message:

void func1() noexcept {
  try {
    do_task();
    do_another_task();
  } catch (const std::out_of_range& e) {
    show_msg("Out of range error", e.what());
  } catch (const std::logic_error& e) {
    show_msg("Logic error", e.what());
  } catch (const std::system_error& e) {
    show_msg("System error", e.what());
  } catch (const std::runtime_error& e) {
    show_msg("Runtime error", e.what());
  } catch (const std::exception& e) {
    show_msg("Generic error", e.what());
  }
}

void func2() noexcept {
  try {
    do_something();
    do_something_else();
    do_even_more();
  } catch (const std::out_of_range& e) {
    show_msg("Out of range error", e.what());
  } catch (const std::logic_error& e) {
    show_msg("Logic error", e.what());
  } catch (const std::system_error& e) {
    show_msg("System error", e.what());
  } catch (const std::runtime_error& e) {
    show_msg("Runtime error", e.what());
  } catch (const std::exception& e) {
    show_msg("Generic error", e.what());
  }
}

我可以只处理 std :: exception 并显示一条通用消息,但是我想更具体一些,这就是为什么我捕获了所有可能的异常.

I could just handle std::exception and show a single generic message, but I want to be more specific, that's why I'm catching all possible exceptions.

我想重用此异常处理代码.我想到了:

I want to reuse this exception treatment code. I thought about this:

void run_treated(std::function<void()> func) noexcept {
  try {
    func();
  } catch // ... all the catches go here
}

void func1() noexcept {
  run_treated([]()->void {
    do_task();
    do_another_task();
  });
}

void func2() noexcept {
  do_something();
  do_something_else();
  do_even_more();
}

  1. 这是一个好方法吗?
  2. 如果是这样, run_治疗将被称为很多.我应该关注性能吗?
  3. 还有其他方法吗?
  1. Is this a good approach?
  2. If so, run_treated will be called a lot. Should I be concerned about performance?
  3. Any other approaches?

推荐答案

可以选择使用

There's the option of using a Lippincott Function to centralize the exception handling logic. Consider this:

void Lippincott () noexcept {
  try {
    throw;
  } catch (const std::out_of_range& e) {
    show_msg("Out of range error", e.what());
  } catch (const std::logic_error& e) {
    show_msg("Logic error", e.what());
  } catch (const std::system_error& e) {
    show_msg("System error", e.what());
  } catch (const std::runtime_error& e) {
    show_msg("Runtime error", e.what());
  } catch (const std::exception& e) {
    show_msg("Generic error", e.what());
  }
}

void func1() noexcept {
  try {
    do_task();
    do_another_task();
  } catch (...) {
    Lippincott();
  }
}

void func2() noexcept {
  try {
    do_something();
    do_something_else();
    do_even_more();
  } catch (...) {
    Lippincott();
  }
}

它如何工作?当您在 func1 func2 中输入处理程序时,将处理当前异常".Lippincott 的正文开始一个新的try..catch块,然后将其重新抛出.然后,它捕获适当的异常并集中处理它们.

How does it work? When you enter the handler in func1 or func2 there is a "current exception" being processed. The body of Lippincott starts a new try..catch block and re-throws it. Then it catches the appropriate exceptions and handles them accordingly in a centralized manner.

您还应该注意,您的异常处理逻辑并非真正地 noexcept .从理论上讲,您的列表中可能没有某些例外.在这种情况下,根据您如何标记事物 noexcept

You should also note that your exception handling logic isn't really noexcept. There could theoretically be exceptions not covered by your list. In which case there are several places for std::terminate to be called, depending on how you mark things noexcept

这篇关于重用C ++中的异常处理代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆