【问题标题】:Throw a derived class in catch scope在捕获范围内抛出派生类
【发布时间】:2021-09-25 08:36:48
【问题描述】:

我想了解导致派生类PE 没有被second catch 捕获的程序中出了什么问题,并像我想要的那样显示错误。 同样,为了运行这个简单的例子,我必须纠正什么

class myEx
{
    int errNum;
public:
    myEx(int e) : errNum(e) {}
    virtual void printErr() { cout << errNum << " "; }
};
class subEx : public myEx
{
    string errDesc;
public:
    subEx(int e, string d) : myEx(e), errDesc(d) {}
    void printErr()
    {
        myEx::printErr();
        cout << errDesc << " ";
    }
};
int main()
{
    try
    {
        myEx* pME = new subEx(0, "err 0");
        throw pME;
    }
    catch (myEx* p)
    {
        p->printErr();
        subEx PE(1, "err 1");
        throw PE;
    }
    catch (subEx e)
    {
        e.printErr();
    }
}

【问题讨论】:

  • 为什么是throwing 指针?为什么先按指针捕获,然后按值捕获?
  • @Jarod42 这是我测试时必须理解的示例

标签: c++ pointers inheritance try-catch throw


【解决方案1】:

try 块一次只能抛出 1 个异常对象。它可以有多个 catch 块来指定它想要捕获的不同类型的异常,但实际上最多只会执行其中的一个,即与实际抛出的异常类型最匹配的一个。

如果没有匹配的catch 块,则异常传播调用堆栈,直到找到匹配的更高的catch 块。

如果匹配的catch 块想要抛出一个新异常(这是完全合法的),您需要更高的try/catch 来捕获它。

另外,不要通过指针抛出/捕获异常。而是按值抛出它们,然后通过引用捕获它们。否则,您会泄漏异常对象,因为当指针超出范围时,catch 将无法正确释放它。

试试这个:

class myEx
{
    int errNum;
public: 
    myEx(int e) : errNum(e) {} 
    virtual void printErr() const
    {
        cout << errNum << " ";
    } 
}; 

class subEx : public myEx
{
    string errDesc;
public: 
    subEx(int e, string d) : myEx(e), errDesc(d) {}
    void printErr() const
    {
        myEx::printErr();
        cout << errDesc << " ";
    }
};

int main()
{
    try
    {
        try
        {
            throw subEx(0, "err 0");
        }
        catch (const myEx &p)
        {
            p.printErr();
            throw subEx(1, "err 1");
        }
    }
    catch (const subEx &e)
    {
        e.printErr();
    }
}

【讨论】:

    【解决方案2】:

    这不像你想的那样工作。

    所有 catch 块都适用于前面的 try 块。您无法在第二个 catch 块中捕获您在第一个 catch 块中抛出的内容。但是,您可以在直接或间接调用您的函数的函数之一的 catch 块中捕获它(这里不是这种情况)。

    【讨论】:

    • 所以如果理解你,就没有办法在 catch 块中扔东西。如果我想抛出第二条语句throw PE,我必须创建另一个尝试。对吗?
    • @Ronyco123 是的,try/catch 一次仅适用于一个异常。如果需要捕获多个异常(甚至多次捕获一个异常),则需要多个try/catch
    猜你喜欢
    • 1970-01-01
    • 2016-07-25
    • 2013-11-18
    • 2012-09-18
    • 1970-01-01
    • 2012-04-07
    • 2015-07-18
    • 2014-05-22
    • 1970-01-01
    相关资源
    最近更新 更多