【问题标题】:Can I install a custom handler for cases when bad_cast is thrown?我可以为抛出 bad_cast 的情况安装自定义处理程序吗?
【发布时间】:2012-04-01 22:24:29
【问题描述】:

如果dynamic_cast<SomeType&> 失败bad_cast 会抛出异常。在我的代码中有一个单独的异常层次结构,bad_cast 不在那个层次结构中,所以我的代码不会处理bad_cast。我可以抛出一些其他异常吗?

我的意思是我想写一个这样的自定义处理程序:

void OnBadCast()
{ 
    throw MyException( "Bad cast" );
}

并以某种方式在 C++ 运行时中注册它

RegisterMyBadCastHandler( &OnBadCast );

以便调用此处理程序而不是抛出 bad_cast

这可能吗?

【问题讨论】:

  • 您可以制作自己的动态转换来包装动态转换并翻译异常
  • 不要抓住它。如果您想尝试并转换,则使用dynamic_cast 的指针形式并在转换后测试null。然后,在需要类型并且std::bad_cast 表示程序中存在错误的情况下使用参考表单。在这种情况下,您希望它冒泡并停止程序
  • @Alexandre C.:立即停止程序并不总是一种选择。有时最好记录异常并继续下一项要做的事情。
  • @sharptooth:这种情况很少见,可以在本地处理。请参阅我的答案以获取更新。

标签: c++ visual-c++ exception error-handling dynamic-cast


【解决方案1】:

我认为你无法改变这种行为。

可以做的是使用你自己的脚轮,但是:

template<class T, class E> T myCast(E expr)
{
    try
    {
        return dynamic_cast<T>(expr);
    }
    catch(std::bad_cast e)
    {
        // custom handler
    }
};

【讨论】:

    【解决方案2】:

    错误的强制转换通常表示程序中的错误(例如超出范围或内存不足),因此根本不应该被捕获(或者可能在顶层)。如果你想在dynamic_cast成功后进行分支,那么以指针形式测试null:

    if (T* p = dynamic_cast<T*>(some_ptr))
    {
        // Do something with p
    }
    

    如果你想要一个特殊的处理程序,你能做的最好的就是:

    template <typename T, typename U>
    T& polymorphic_cast(U& x)
    {
        if (T* p = dynamic_cast<T*>(&x)) return *p;
    
        my_handler();
    }
    

    my_handler 应该杀死程序(并可能记录错误)。但在这里,您可能更喜欢使用简单的dynamic_cast&lt;T&amp;&gt; 表单,让std::bad_cast 冒泡并在顶层记录。这也与调试器配合得更好,可以将其设置为在强制转换失败时停止。

    像您在 cmets 中描述的情况非常罕见,需要特别考虑,例如:

    if (auto p = dynamic_cast<foo*>(q)) { do_something(); }
    else { throw bail_me_out_of_here(); }
    

    可用于指示某些上游战略家应该尝试另一种方法。

    【讨论】:

      【解决方案3】:

      您不需要在同一层次结构中拥有异常来处理它们。至少在 VC++ 中没有。如果您只是担心处理不同类型的错误,请执行以下操作。如果这个答案还不够,考虑到您正在使用的限制,其他答案非常好,但请注意何时抛出 bad_cast 以及何时不抛出。 http://answers.yahoo.com/question/index?qid=20071106101012AAggZAk

      #include <iostream>
      #include <exception>
      
      using namespace std;
      
      class my_exception {
      public:
          explicit my_exception() {};
          const char* msg() const { return "my_exception"; }
      };
      
      int main()
      {
      
          try {
      
              // comment either line.
              throw std::exception("std::exception");
              throw my_exception();
      
          }
          catch (const std::exception& e )
          {
              cout << e.what() << endl;
          }
          catch (const my_exception& e)
          {
              cout << e.msg() << endl;
          }
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 2018-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多