为什么重新抛出的异常不能按预期工作?

时间:2015-07-26 15:41:27

标签: c++ exception inheritance

我的示例代码:

#include<iostream>
using namespace std;

class Parent{ 
        public: 
            virtual void who()
            {
                cout<<"I am parent"<<endl;
            }
};
class Child: public Parent 
{
    public: 
        void who()
        {
            cout<<"I am child"<<endl;
        }
};

int main()
{
    try{
        try{
            Child C;
            Parent &P=C;
            throw P;
        }
        catch(Parent &P)
        {
            P.who();
            throw;//here it just propagates the Child exception
        }
    }
    catch(Parent &P)
    {
            P.who();//parent who is getting executed
    }

}

我正在阅读Scott Meyers更有效的C ++,第12项。所以当我重新抛出它时,它应该传播Child异常。但外部catch P.who()会给出父who()。 当我将外部捕获更改为Child类型(程序中未提及)时,它会终止该过程。我的理解在哪里错了?

Scott Meyers所说的(我的编辑)

class Widget{...};
class Special Widget: public Widget { ... };
void passAndThrowWidget()
{
   SpecialWidget localSpecialWidget;
   ...
   Widget& rw = localSpecialWidget;
   throw rw; //this throws an exception of type Widget!
} 

................
................

catch(Widget &w)   //catch Widget exceptions
{
  ...
  throw;     //rethrow the exception so it continues to propagate.
}
.............
.............

如果最初抛出的异常是Special Widget类型,catch块会传播Special Widget异常,即使w的静态类型是Widget。这是因为重新抛出异常时不会复制。

1 个答案:

答案 0 :(得分:3)

throw rw; //this throws an exception of type Widget!

这不会引发SpecialWidget。它只会抛出Widget

throw;永远不会更改抛出对象的类型。如果原始对象是Child,则它仍然是throw;之后的孩子。