Why throw at derived class catches by base?

爷,独闯天下 提交于 2019-12-02 04:01:41

Reason:

Upcasting

of derived class to base. and hence always getting stuck on the first catch.

Change the order of the catch blocks to fix that behavior:

#include <iostream>

class EA {};
class EB: public EA {};

void F()
{
  throw EB();  // throw at EB().
}

int main()
{
  try
  {
    F();
  }
  catch(EB&) // why not me? every time?
  {
    std::cout<<"EB Exception";
  }
  catch(EA&) // caught here??
  {
    std::cout<<"EA Exception";
  }

  std::cout<<" Finished"<<std::endl;

  return 0;
}

The compiler even warns you about this:

main.cpp:21:3: warning: exception of type 'EB' will be caught
   catch(EB&) // why not me? every time?
   ^~~~~
main.cpp:17:3: warning:    by earlier handler for 'EA'
   catch(EA&) // caught here??
   ^~~~~

As mentioned by the standard in [except.handle] (working draft):

The handlers for a try block are tried in order of appearance. That makes it possible to write handlers that can never be executed, for example by placing a handler for a derived class after a handler for a corresponding base class.

That's exactly what you did. Interesting indeed.
Invert the handlers to solve the issue.

Because the catch blocks check in the order you declare them.

you first catch by EA&. EB is derived from EA, so this is a valid catch and the second catch gets ignored.

You want to have the most "specialized" exception-catch first. So if you switch the catch blocks it should work the other way.

catch statements are inspected in order. EA& matches, so it is used. EB& can never be matched. You need to put the more specific catch first.

  catch(EB&) // Will catch
  {
    std::cout<<"EB Exception";
  }
  catch(EA&) // and this would catch EA objects that aren't EB.
  {
    std::cout<<"EA Exception";
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!