从构造函数捕获Exception,而不将对象隐藏在try块中
Catch Exception from constructor without hiding the object in the try block
我有一个类,它的构造函数可能抛出异常。
class A {
A() { /* throw exception under certain circumstances */ }
};
我想在客户端为堆栈分配的实例捕获此异常。但是我发现自己不得不扩展try
块,至少到实例必须是活的为止。
try {
A a;
do_something(a);
} catch {
// ...
}
现在,当try块太大而无法追踪异常的来源时,这显然成为一个问题:
try {
A a1;
A a2;
do_something(a1, a2);
} catch {
// Who caused the exception?
}
我该怎么做才能避免这种情况?
:
似乎我没有很好地解释这个问题:出于显而易见的原因,我想让try块跨越尽可能少的代码(也就是说,只有构造)。
但是这会产生一个问题,我不能在之后使用对象,因为它们已经移出了作用域。
try {
A a1;
} catch {
// handle a1 constructor exception
}
try {
A a2;
} catch {
// handle a2 constructor exception
}
// not possible
do_something(a1, a2);
不需要更改A
的解决方案是使用嵌套的try/catch块:
try {
A a1;
try {
A a2;
do_something(a1, a2);
}
catch {
// a2 (or do_something) threw
}
} catch {
// a1 threw
}
使用堆构造对象而不是堆栈构造对象,这样您就可以测试哪些对象已经成功构造,例如:
// or std::unique_ptr in C++11, or boost::unique_ptr ...
std::auto_ptr<A> a1_ptr;
std::auto_ptr<A> a2_ptr;
A *a1 = NULL;
A *a2 = NULL;
try
{
a1 = new A;
a1_ptr.reset(a1);
}
catch (...)
{
}
try
{
a2 = new A;
a2_ptr.reset(a2);
}
catch (...)
{
}
if( (a1) && (a2) )
do_something(*a1, *a2);
或者(仅当A
是可复制构造的):
boost::optional<A> a1;
boost::optional<A> a2;
try
{
a1 = boost::in_place<A>();
a2 = boost::in_place<A>();
}
catch (...)
{
//...
}
if( (a1) && (a2) )
do_something(*a1, *a2);
另一种在某些情况下可能很方便的方法:
class ExceptionTranslatedA : public A {
public:
template<typename Exc>
ExceptionTranslatedA(Exc exc)
try : A() {}
catch (unhelpful_generic_exception) {
throw exc;
}
};
如果抛出一个不同的异常是你想在原来的try-catch块中做的所有事情,这是特别有用的,因为你可以完全摆脱它。它也比为控制流引入布尔变量(即使它们隐藏在boost::optional
中)感觉更优雅。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 为什么本地静态对象的初始化使用隐藏的防护标志?
- 如何在使用C++打开隐藏的 COM 对象时隐藏控制台窗口
- 如何在C++共享库中隐藏业务对象的实现细节并提供接口
- C++窗体-单击按钮后如何显示/隐藏某个对象(如按钮或文本框)
- 隐藏QSplitter子对象,但保留控制柄的位置
- 如何使用英特尔预取pragma时,数据隐藏在一个对象
- Boost的ASIO和隐藏那些棘手的io_service对象
- 由shared_ptr管理的对象的C++隐藏构造函数
- 从构造函数捕获Exception,而不将对象隐藏在try块中