0

我已经创建了自己的异常类,它派生自runtime_errorc'tor 并在 c'tor 中得到一个 int。

我想为这个异常创建一个基类,以便使用多态性,所以我只能捕获基类,基本上我会捕获派生类,然后从中调用 .what() 方法。

所以,这是基类:(在另一个 cpp 文件中我得到了 baseException::~baseException(){})

class baseException
{
    virtual ~baseException()=0 {}
    virtual const char* what()=0;
};

这是派生类:

class myException: public runtime_error, public baseException
{
public:
    myException(int): runtime_error("Error occured") {}
    const char* what() {return runtime_error::what();}
};

但是当我主要写:

catch(baseException* x)
{
cout<<x->what();
}

它只是跳过它并且不进入块,即使 myException 继承自 baseException。有什么建议吗?

4

4 回答 4

2

baseException没有该what方法,您可能应该只是baseExceptionruntime_error.

class baseException : public runtime_error
{
public:
    baseException(const std::string& what) : runtime_error(what) {}
};

接着

class myException: public baseException
{
public:
    myException(int): baseException("Error occured") {}
};

虽然我更喜欢以下成语:

class myException: public baseException
{
public:
    myException(int x): baseException(getWhatMessage(x)) {}

private:
    static std::string getWhatMessage(int x) { /*generate the message*/ }
};

catch部分而言。如果你抛出 using throw myException(5),那么你应该像这样捕获

catch(baseException& x)
{
    cout<<x.what();
}
于 2012-06-18T13:04:53.420 回答
2

您应该通过引用(或 const 引用)而不是指针来捕获异常。

于 2012-06-18T13:01:13.283 回答
1

更新:此答案基于问题的原始版本。现在看来问题不是在调用what()(因为您已经通过在基类中重新声明它来解决这个问题)。问题只是你试图捕捉一个指针并(我猜)抛出一个值;解决方案是通过引用捕获:

catch (myException const & ex) {
    std::cerr << ex.what() << std::endl;
}

(假设您将声明修复what()const;如果由于某种原因您确实需要它为非,则从该行const中删除)。constcatch

what()原始答案描述了如果未在以下声明中如何调用baseException

我想抓baseException*

你最好抓住baseException const &; 没有明智的方法来抛出指针。

并调用他们的.what()方法

如果你想打电话what(),那么你最好接电话std::exception const &;除非您还想从基类中获得一些功能。在这种情况下,也许你的基类应该继承自std::runtime_error; 或者它应该继承自std::exception,在这种情况下,您的myException类型将需要使用虚拟继承。

如果您真的想what()从您的班级访问,那么您需要交叉转换为std::exception

catch (myException const & ex) {
    std::cerr << dynamic_cast<std::exception const &>(ex).what() << '\n';
}
于 2012-06-18T13:10:27.973 回答
1

你捕捉到一个baseException对象的引用;因此,您只知道该类的方法。baseException虽然没有一个成员被调用what()。这会导致错误。使baseException派生runtime_error或直接捕获myException

编辑:

这段代码表明,指针不应该与异常一起工作是绝对没有理由的:

#include <iostream>
#include <string>

class A {
public:
    virtual int test() = 0;
};

class B : public A {
public:
    virtual int test() {
        return 42;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    try {
        throw new std::string("foo");
    } catch (std::string* ecx){
        std::cout << *ecx << std::endl;
    }

    try {
        throw new B();
    } catch (A* ecx) {
        std::cout << ecx->test() << std::endl;
    }
}

输出:

42

于 2012-06-18T13:01:36.823 回答