我正在try/catch块中创建我的类的对象,并希望在发生异常时在catch块中访问它。即使对象创建得很好,我也无法在catch块中访问它,因为它在块外声明。
try {
MyObject ob(arg1,arg2); //this can trow exception
ob.func1(); //this also can throw exception
} catch (std::exception& ex){
//I want to access ob here if it was constructed properly and get the reason why func1() failed
}
我可以使用嵌套的try/catch块来解决这个问题,但有其他方法可以解决这个吗
try {
MyObject ob(arg1,arg2); //this can trow exception
try {
ob.func1(); //this also can throw exception
} catch(std::exception& ex) {
//object was constructed ok, so I can access reason/state why the operation failed
}
} catch (std::exception& ex){
//object failed to construct
}
不,你不能这样做。不可能从同一级别的catch块访问此变量。
解决方案是停止使用异常作为流控制机制——它们不是——并按原样使用它们,这表明出现了异常情况——在这种情况下,抛出什么并不重要。
否,不能访问范围外的对象。但要回答这个问题:
获取func1()失败的原因
如果对象构造由于异常而失败,这意味着std::异常已经包含了一些关于它失败原因的信息。所以你必须在你的代码中这样做:
catch (std::exception& ex){
// object failed to construct
std::cout << ex.what() << std::endl;
}
Andrei Alexandrescu的ScopeGuard可能会在这里有所帮助:
try {
MyObject ob(arg1,arg2);
SCOPE_FAIL { /* Handler 1 */ };
ob.func1();
} catch (std::exception& ex) {
/* Handler 2 */
}
如果SCOPE_FAIL
的作用域通过堆栈展开而保留,即抛出异常,则会执行其主体。不幸的是,您无法在那里访问异常本身,但您可以访问ob
。
程序的其余部分照常运行,因此执行看起来像:
- CCD_ 3构建成功
- 执行CCD_ 4并抛出
- 执行CCD_ 5
- CCD_ 6被破坏
- 执行CCD_ 7