在 catch 范围内抛出派生的 class

Throw a derived class in catch scope

我想了解导致 PE 派生的 class 没有被 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();
    }
}

这并不像你想象的那样有效。

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

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

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

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

此外,不要 throw/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();
    }
}