我正在学习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上它可以做到这一点.
从我在各个帖子上看到的我所做的是正确的,所以我错过了什么.
你的what()
回报:
return exception::what();
从返回值std::exception::what()
的规定如下:
指向带有解释性信息的以null结尾的字符串的指针.
而已.没有别的,没有别的.您显示的文本当然有资格作为"解释性信息".这是返回值的唯一要求what()
(除了另一个与此不相关的另一个).
换句话说,C++并不能保证您获得的内容的确切内容what()
.正如俗话所说,what()
你看到的就是what()
你得到的.
如果您希望您的例外描述自己,在某种程度上,由您来实现它,作为您的一部分what()
.
您需要自己实现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
实现实例,则需要使用引用.