假设您收到了以下代码:
blah & Foo::foo() {
if (_x) { return _blah;}
throw exception("blah error");
}据我所知,调用它的唯一方法是在这样的try/catch块中调用它。
try {
blah &b=_foo.foo();
catch(...) {}现在b超出了范围,使得错误处理有些困难。可以将其赋值给指针,然后将指针重新分配到下面的引用,但这似乎相当困难。
我不记得有一个明确的建议,即避免创建返回引用或抛出异常的函数,但是在处理这些接口时,有什么标准的方法可以绕过这个问题吗?
发布于 2014-02-26 02:48:28
那么,诀窍是设计您的异常、异常处理程序和错误处理程序,这样您就不会遇到这样的情况。例如,可以将所有依赖于foo()成功返回的操作封装在try块中,这允许您一次性处理任何这些操作引发的异常。从概念上讲,您是在“尝试”执行整个任务,而不是试图独立执行单个步骤,例如:
try {
blah &b = _foo.foo();
b.dehydrate();
_foo.reconceptualize(b);
idealize(b, _foo, "grumble");
} catch (const exception &x) {
// log/handle error
}另一种思考方法是,如果引用b的有效性取决于foo()的成功,那么代码中只有一个地方b是有效的,那就是在调用foo()之后的try块中。一旦您离开try块,就无法保证b的有效性,因为在这一点上,异常可能发生,也可能没有发生。
try {
blah &b = _foo.foo();
// <- [1] this is the only point that we *know* foo() returned something valid
} catch (...) {
// <- [2] here we *know* it didn't
}
// <- [3] here we don't know either way现在,如果您的代码依赖于foo()的成功和b的有效性,并且必须选择上面的位置1、2或3,那么您认为哪个位置最合适(提示: 1)?
即使您使用在try块之前声明的指针,使用例如NULL来指示抛出异常也是相当多余的,因为您以前已经获得了该信息:
blah *b;
try {
b = _foo.fooptr();
// <- here we know an error did not occur
} catch (...) {
// <- here we know an error occurred
b = NULL; // <- so why do this...
}
// ... when we already had a perfectly good opportunity to handle above;
// we've kind of missed the boat at this point.这并不是说指针示例没有用处的情况。也许您不想做任何特殊的错误处理,或者您正在抽象其他一些API:
void * getData () {
void *data = NULL;
try {
data = getFromThingThatMayThrow();
} catch (...) {
// we really don't care why it failed, and it's more convenient to
// swallow it and return NULL instead.
}
return data;
}但重点是,如果您发现您的异常处理变得非常奇怪和混乱,在您的例子中,您可能走错了道路,您应该考虑后退一步,重新评估您的错误处理。如果使用得当,异常可以极大地简化错误处理和恢复。
发布于 2014-02-26 02:40:59
在你身边似乎有一种误解。如果上面的函数抛出一个异常,它就不会完成,并且它会而不是产生一个引用。try/catch块中的引用不仅不可访问,而且根本不存在。
抛出异常的函数是而不是返回的。
发布于 2014-02-26 02:33:15
正如chris在他的评论中提到的那样,您确实处理了不同于返回代码的异常,因为您没有包装每个函数调用,这些函数调用可能会抛出自己的try/catch处理程序。
不像每次函数调用之后那样检查异常,而是将异常处理推到最适合处理异常所指示的故障的层。该代码很可能比当前代码高出几层。
至于返回引用,有一些指南,比如不返回对本地对象的引用。在您的示例中,您可能会返回一个对成员的引用,只要您确保不会遇到对象生存期问题,这可能是可以的。
https://stackoverflow.com/questions/22030475
复制相似问题