当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在C++中创建自定义异常》经验,为你挑选了2个好方法。

我正在学习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上它可以做到这一点.

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



1> Sam Varshavc..:

你的what()回报:

 return exception::what();

从返回值std::exception::what()的规定如下:

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

而已.没有别的,没有别的.您显示的文本当然有资格作为"解释性信息".这是返回值的唯一要求what()(除了另一个与此不相关的另一个).

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

如果您希望您的例外描述自己,在某种程度上,由您来实现它,作为您的一部分what().


鉴于`TestClass`继承了`std :: runtime_error`,它可以避免重新实现`what()` - `std :: runtime_error :: what()`已经返回传递给它的构造函数的消息.

2> 小智..:

您需要自己实现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()只有在你阅读它们之后 - 链接.

在你的try-catch中:

catch (const TestClass& myException)

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

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有