我有异常问题:
#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;
}
我想打印“DIVIDED BY 0”,但我得到:
terminate called after throwing an instance of 'except'
what(): std::exception
Aborted
Process returned 134 (0x86)
我应该把noexcept
放在每个不抛出任何异常的函数/成员函数中吗?
err[strlen(s)] = 0
是必要的吗? (在except :: except(const char * s)中除外)
我想打印“DIVIDED BY 0”但我得到:在抛出“除外”的实例后终止调用
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