首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何调用返回引用或抛出异常而不使用体操的函数?

如何调用返回引用或抛出异常而不使用体操的函数?
EN

Stack Overflow用户
提问于 2014-02-26 02:26:32
回答 4查看 826关注 0票数 3

假设您收到了以下代码:

代码语言:javascript
复制
blah & Foo::foo() { 
   if (_x) {  return _blah;}
   throw exception("blah error");
}

据我所知,调用它的唯一方法是在这样的try/catch块中调用它。

代码语言:javascript
复制
try {
blah &b=_foo.foo();
catch(...) {}

现在b超出了范围,使得错误处理有些困难。可以将其赋值给指针,然后将指针重新分配到下面的引用,但这似乎相当困难。

我不记得有一个明确的建议,即避免创建返回引用或抛出异常的函数,但是在处理这些接口时,有什么标准的方法可以绕过这个问题吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-26 02:48:28

那么,诀窍是设计您的异常、异常处理程序和错误处理程序,这样您就不会遇到这样的情况。例如,可以将所有依赖于foo()成功返回的操作封装在try块中,这允许您一次性处理任何这些操作引发的异常。从概念上讲,您是在“尝试”执行整个任务,而不是试图独立执行单个步骤,例如:

代码语言:javascript
复制
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的有效性,因为在这一点上,异常可能发生,也可能没有发生。

代码语言:javascript
复制
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来指示抛出异常也是相当多余的,因为您以前已经获得了该信息:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
}

但重点是,如果您发现您的异常处理变得非常奇怪和混乱,在您的例子中,您可能走错了道路,您应该考虑后退一步,重新评估您的错误处理。如果使用得当,异常可以极大地简化错误处理和恢复。

票数 0
EN

Stack Overflow用户

发布于 2014-02-26 02:40:59

在你身边似乎有一种误解。如果上面的函数抛出一个异常,它就不会完成,并且它会而不是产生一个引用。try/catch块中的引用不仅不可访问,而且根本不存在。

抛出异常的函数是而不是返回的。

票数 2
EN

Stack Overflow用户

发布于 2014-02-26 02:33:15

正如chris在他的评论中提到的那样,您确实处理了不同于返回代码的异常,因为您没有包装每个函数调用,这些函数调用可能会抛出自己的try/catch处理程序。

不像每次函数调用之后那样检查异常,而是将异常处理推到最适合处理异常所指示的故障的层。该代码很可能比当前代码高出几层。

至于返回引用,有一些指南,比如不返回对本地对象的引用。在您的示例中,您可能会返回一个对成员的引用,只要您确保不会遇到对象生存期问题,这可能是可以的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22030475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档