让我们说我的函数意味着返回一个类,但是,我希望在调用构造函数时使用异常处理。问题是,在例外的情况下,我想要返回的课程超出范围,我没有任何回报:
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 {}中使用该类的实用方法。感谢
答案 0 :(得分:2)
有几种方法可以解决这个问题。第一种是更改返回函数的返回类型,而不是按值返回类,将它传递给std::unique_ptr
。 std::unique_ptr
可以为null,因此如果有异常,您可以返回null unique_ptr
,否则只需将unique_ptr
返回到您创建的对象。
另一种选择是使用boost::optional
或std::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
看起来错位了。考虑在客户端代码中捕获异常或重新抛出异常。否则,该函数应该能够恢复并返回成功创建的对象。