[英]Exceptions & C-style strings
我有异常问题:
#include <iostream>
#include <cstring>
#include <exception>
class except :public std::exception
{
char* err;
public:
except(const char* s) noexcept
{
err = new char[strlen(s) + 1];
strcpy(err, s);
err[strlen(s)] = 0; //is it necessary??
}
virtual const char* what() noexcept
{return err;}
virtual ~except() noexcept
{delete err;}
};
double div(const double& a, const double& b) noexcept
{
if (b == 0.0)
throw except("DIVIDED BY 0");
return a / b;
}
int main()
{
try
{
std::cout << div(5.0, 0.0);
}
catch (std::exception &ex)
{
std::cout << ex.what();
}
return 0;
}
我想打印“除以 0”,但我得到:
terminate called after throwing an instance of 'except'
what(): std::exception
Aborted
Process returned 134 (0x86)
我noexcept
在每个不抛出任何异常的函数/成员函数中放置noexcept
吗?
err[strlen(s)] = 0
有必要? (在 except::except(const char* s) 中)
我想打印“DIVIDED BY 0”,但我得到:在抛出一个 'except' 实例后调用终止
double div(const double& a, const double& b) noexcept
你声称你不会抛出异常,但你在撒谎。 结果是在您实际抛出时调用 std::terminate。
这个问题实际上是双重的。 首先,正如@manni66 所建议的那样,不应将div
声明为noexcept
,这确实会导致运行时错误,但删除它并不能解决问题。
第二个问题是, what
已经声明:
virtual const char* what() noexcept;
而它在std::exception
声明为:
virtual const char* what() const noexcept;
并且签名的这种差异意味着当它被std::exception
的处理程序捕获时,它调用std::exception::what()
而不是except::what()
有几点值得一提:
std::string
类。 这将使事情变得更容易和更安全。 尽管在这种情况下,正如第二点所回避的那样,字符串成员并不是真正必要的,因为该类足够具体,不需要进一步限定。std::runtime_error
或在这种情况下std::overflow_error
将是不错的选择,并且都将std::string
作为构造函数的参数,因此无需创建自己的异常类。例如:
#include <exception>
using namespace std;
class divide_by_zero : public std::exception
{
public:
virtual const char* what() const noexcept { return "DIVIDED BY 0"; }
};
double div(const double& a, const double& b)
{
if (b == 0.0)
throw divide_by_zero();
return a / b;
}
int main()
{
try
{
std::cout << div(5.0, 0.0);
}
catch (divide_by_zero &ex)
{
std::cout << ex.what();
}
catch (std::exception &ex)
{
std::cout << ex.what();
}
return 0;
}
输出:
DIVIDED BY 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.