我有一段网络代码会抛出各种异常,这些异常都会在一般的catch异常声明中被捕获。
try {
network code
} catch (Exception e) {
freeaddrinfo(some_address);
}
此方法的问题是异常中的freeaddrinfo。并非所有异常情况都可以/应该调用freeaddrinfo,并且在我的特定情况下,当存在无效地址传递到网络代码以连接某处时,不应调用freeaddrinfo。我解决这个问题的想法是检索此异常抛出的错误代码,并可能将其与e.to_string结合使用来处理这种边缘情况。根据我从Effective Java中学到的知识,这是处理这个问题的一种脆弱方法。你建议我做什么?
答案 0 :(得分:2)
在C ++中,在异常之后释放资源的常用方法不是捕获异常,而是将资源包装在析构函数负责释放的对象中。这样,当管理对象超出范围(或以其他方式销毁)时,无论是否抛出异常,它都会被释放。这种技术称为RAII。
(非常基本的)管理对象可能如下所示:
struct AddressInfo {
addrinfo * info;
// Constructor takes ownership of resource
explicit AddressInfo(addrinfo * info) : info(info) {}
// Destructor releases resource
~AddressInfo() {freeaddrinfo(info);}
// Prevent shallow copying, so only one object manages the resource
AddressInfo(AddressInfo const &) = delete;
void operator=(AddressInfo const &) = delete;
};
然后你的代码将成为:
// some network code
AddressInfo address(some_address);
// some more network code
,无需任何异常处理或手动清理代码。
答案 1 :(得分:1)
如果您坚持使用异常,那么网络代码应根据错误的性质引发一个非常特殊的异常(类型)。也就是说,网络代码应该引发一个异常,就其本质而言,暗示是否可以调用freeaddrinfo()
。
答案 2 :(得分:0)
创建更具体的异常并抛出它们?然后你可以先捕获它们,然后再回到普通捕获物上。
try {
network code
}
catch (SomeException1 e) { freeaddrinfo(some_address); }
catch (SomeException2 e) { freeaddrinfo(some_address); }
catch (Exception e) { }