c++ - 在 catch 范围内抛出派生类

标签 c++ pointers inheritance try-catch throw

我想了解导致 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();
    }
}

最佳答案

一个 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();
    }
}

关于c++ - 在 catch 范围内抛出派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68410706/

相关文章:

c++ - basic boost date_time 输入格式问题

c++ - 声明指针时更改 asterick 的位置

Char 数组指针(通过 'reference' 传递)未分配(sscanf 变量更改后)

c++ - 如何使 void* 参数在函数中保存其局部结果,该函数使用 struct * 调用?

c++ - C++子类构造函数被忽略

c++ - 将基类的对象传递给派生类的引用函数

c++ - 什么更快 : recreate or clear()?

c++ - 在 void 指针上使用 new

c - 指针数组外部问题

c++ - 基类有虚方法,子类有非虚方法。即使它是非虚拟的,仍然如何调用子类方法