在C ++中创建自定义异常

时间:2017-01-19 23:06:45

标签: c++ exception

我正在学习C ++,当我尝试创建自己的异常并将它们放在Linux上时,我遇到了这种情况。

我已经创建了一个小测试项目来测试我的实现,下面是我的异常类头文件。

class TestClass : public std::runtime_error
{
public:
    TestClass(char const* const message) throw();
    virtual char const* what() const throw();
};

异常类的源文件是

using namespace std;

TestClass::TestClass(char const* const message) throw()
    : std::runtime_error(message)
{

}

char const * TestClass::what() const throw()
{
    return exception::what();
}

在我的主应用程序中,我正在调用一个抛出异常并在try / catch中捕获它的函数,如下所示:

void runAFunctionAndthrow();

/*
 * 
 */
int main(int argc, char** argv) {
    try
    {
        cout << "About to call function" << endl;
        runAFunctionAndthrow();
    }
    catch (TestClass ex)
    {
        cout << "Exception Caught: " << ex.what() << endl;
    }

    return 0;
}

void runAFunctionAndthrow()
{
    cout << "going to run now. oh dear I need to throw an exception" << endl;

    stringstream logstream;
    logstream << "This is my exception error. :(";
    throw TestClass(logstream.str().c_str());
}

当我跑步时,我希望得到以下输出:

  

即将召集功能

     

立即开始行动。哦,亲爱的,我需要抛出异常

     

异常捕获:这是我的异常错误。 :(

相反,我得到的是

  

即将召集功能

     

现在要跑。哦,亲爱的,我需要抛出异常

     

异常捕获:std :: exception

注意它的最后一行是std :: exception而不是我的实际异常消息“这是我的异常错误”。

为什么会这样,它在Windows上运行正常,但在Linux上它可以做到这一点。

从我在各个帖子上看到的我所做的事情是正确的,所以我错过了什么。

3 个答案:

答案 0 :(得分:25)

您的what()返回:

 return exception::what();

std::exception::what()的返回值为specified as follows

  

指向带有解释性信息的以null结尾的字符串的指针。

那就是它。没有别的,没有别的。您显示的文字当然有资格作为&#34;解释性信息&#34;。这是what()的返回值的唯一要求(除了另一个在这里没有密切关系的那个)。

换句话说,C ++并不能保证what()获得的内容的确切内容。 what()你看到的是what(),正如俗语所说的那样。

如果您希望您的例外情况以某种方式描述自己,那么您可以将其作为what()的一部分来实现。

答案 1 :(得分:16)

您需要自己实现what()方法或使用std::runtime_error::what(),如评论中所述

说:

class TestClass : public std::runtime_error
{
    std::string what_message;
public:
    const char* what() override
    {
        return what_message.c_str();
    }
};

此外,更好地使用noexcept代替throw(),并且只有在您阅读了它们之后才能使用link

在你的try-catch中:

catch (const TestClass& myException)

而不是catch(TestClass myException) - 否则你会做一个可能导致异常抛出的隐式副本。它还打破了多态性:如果你想要catch pure virtual interface实现实例,你需要使用引用。

答案 2 :(得分:0)

您需要一种方法来指定std :: exception的自定义错误消息,不允许使用afaik。有关可能的解决方案,请参阅this