我想知道为给定程序定义自己的异常类通常是一个好习惯。例如,我有一个程序,主要是读取/写入文件,并修改iptables规则。我也把程序写成了自己的基本记录器类。要处理意外值或错误(如打开文件),我通常使用std::runtime_error
。我想知道定义我自己的异常类通常是个好主意。例如:
void Protocol::set_port(const unsigned long &port) {
if ( (port > 0) && (port < 65535) ) {
port_ = port;
}
else {
throw std::invalid_argument("Invalid port number");
}
}
我不喜欢使用一大堆try和catch块,因为我发现这是一个糟糕而丑陋的练习(虽然我可能错了)。
答案 0 :(得分:1)
我想知道为给定程序定义自己的异常类通常是一个好习惯。
是的,通常,异常的类型应该描述源或原因,因此您可以通过模式匹配而不是代码来处理该特定异常。
我通常使用std :: runtime_error。我想知道定义我自己的异常类通常是个好主意。
是的,一般来说,您应遵循以下规则:
显然,只使用例外情况来报告异常故障(即前提条件未得到满足,或资源因程序错误操作而无法使用)。
如果失败是一个逻辑错误(调用者试图在您的程序域中执行非法操作),那么从std::logic_error
派生您的例外。
如果失败是无效参数的结果,那么从std::invalid_argument
派生是有意义的。
如果失败是运行时错误(例如文件丢失),则从std::runtime_error
派生。
嵌套异常也很有用,因为您可以传递摘要和异常原因以供以后诊断,例如:
struct port_out_of_range : std::invalid_argument
{
port_out_of_range(std::string const& context, unsigned long given)
: std::invalid_argument(context + ": port given: " + std::to_string(given))
{
}
};
void Protocol::set_port(const unsigned long &port)
{
if ( port < 65535 ) {
port_ = port;
}
else {
throw port_out_of_range("Protocol::set_port", port);
}
}
...稍后......
try {
// ... some things ...
foo.set_port(x);
// ... more things ...
}
catch(port_out_of_range& e)
{
// maybe some remedial action possible here
}
catch(std::exception& e)
{
// but not here
log(e);
throw;
}