我正在学习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上它可以做到这一点。
从我在各个帖子上看到的我所做的事情是正确的,所以我错过了什么。
答案 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。