在具有异常处理的函数中返回一个类

时间:2017-01-04 12:54:01

标签: c++ oop error-handling

让我们说我的函数意味着返回一个类,但是,我希望在调用构造函数时使用异常处理。问题是,在例外的情况下,我想要返回的课程超出范围,我没有任何回报:

myclass GetClass() {
    try {
        myclass classtoreturn(7);
        return classtoreturn;
    } catch ( const std::exception& ex ) {
        //
    } catch ( const std::string& str ) {
        //
    } catch (...) {
        //
    }

    return ??;
}

但是,如果我在try / catch之外声明该类,我将会遇到一个未初始化类的问题:

myclass GetClass() {
    myclass classtoreturn;
    try {
        classtoreturn(7);
        return classtoreturn;
    } catch ( const std::exception& ex ) {
        //
    } catch ( const std::string& str ) {
        //
    } catch (...) {
        //
    }

    return classtoreturn;   //Unitialized!
}

我的第一个问题是返回一个指针,并在发生异常时返回一个NULL指针,但是指针指向一个超出范围的类,这仍然是不好的。似乎这是一个常见的问题,但我没有偶然发现一个解决方案。

此外,可以看到实际的应用程序here,我试图将gpsmm类返回到我的main函数,以便稍后可以作为指向轮询函数的指针传递。

谢谢!

好的,现在阅读一些回复我认为在调用者处捕获异常是有意义的,但是,我认为这只会向调用者传播问题:

void main() {
    try{
        myclass classforuse{ GetClass() };
    } catch (...) {
        //
    }

    //Want to do something with "classforuse" but it's out of scope!
}

据我所知,当我声明它时,这个类会被构建,所以我没办法从try {}中构造一个类,然后在同一个try {}的范围之外使用它使用std / boost :: optional。那是对的吗?我认为增强库将是我唯一的选择,除非我找到在同一个try {}中使用该类的实用方法。感谢

3 个答案:

答案 0 :(得分:2)

有几种方法可以解决这个问题。第一种是更改返回函数的返回类型,而不是按值返回类,将它传递给std::unique_ptrstd::unique_ptr可以为null,因此如果有异常,您可以返回null unique_ptr,否则只需将unique_ptr返回到您创建的对象。

另一种选择是使用boost::optionalstd::optional。您现在可以使用boost::optional,但std::optional是C ++ 17功能,因此可用性有限。就个人而言,我更喜欢可选方法,因为它只是通过其类型来描述情况。 optional还有一个额外的好处,就是没有动态内存分配。

最后你无法恢复并抛出函数。这将向调用者发出信号,表明发生了某些事情并且没有返回对象。

答案 1 :(得分:1)

我对您的问题的理解是,如果发生异常,您的函数无法履行返回有效myclass对象的义务,并且您不确定如何处理它。抛出异常的第一个解决方案,也许是导致异常失败的异常。在catch块内,您可以使用空throw;语句来重新抛出相同的异常。

catch(const std::exception & err) {
    // do whatever it is you need to do (logging?)
    throw; // this statement throws 'err' again
}

我不知道你是否希望对这些异常做任何事情(你的捕获块是空的,但可能是为了简洁)但通常,如果你不能在这里解决问题,不要试图抓住例外。只需删除整个try / catch并让异常传播。

如果您的功能无法接受,那么您必须更改功能以返回myclass以外的其他内容。如果您有权访问C ++ 17,请考虑使用std::optional或类似的包装器。

答案 2 :(得分:0)

catch看起来错位了。考虑在客户端代码中捕获异常或重新抛出异常。否则,该函数应该能够恢复并返回成功创建的对象。