假设我们有一个可能抛出异常的构造函数。
class A{
public:
A(); // may throw exceptions
};
我们可以使用这种方式来捕获异常:
try{
A a;
// do somethings to a, and I have to put everything about a here
}catch(...){
// handle exceptions
}
所以我的问题是如何避免在try-catch
不使用指针的情况下将所有内容放入块中。
您可以定义一个创建函数来为您处理异常,并在出现异常时返回明智的默认值,例如:
struct A
{
A() : data("Default")
{
std::cout << "In A()" << std::endl;
}
A(const A& other) : data(other.data)
{
std::cout << "In A(A)" << std::endl;
}
A(bool param)
{
std::cout << "In A(bool)" << std::endl;
if(param)
throw std::runtime_error("Failed");
data = "Hello";
}
std::string data;
};
A createA(bool param, A& def_a)
try
{
return A(param);
}
catch (...) {
//...
return def_a;
}
然后,您可以A
使用该函数的返回值初始化实际值。由于RVO,如果创建成功,则仅在失败时将不执行任何复制(因为必须先复制默认值):
int main(int argc, char**args)
{
A defA;
A a1 = createA(true, defA);
A a2 = createA(false, defA);
std::cout << "A1: " << a1.data << std::endl;
std::cout << "A2: " << a2.data << std::endl;
return 0;
}
输出为:
In A()
In A(bool)
In A(A)
In A(bool)
A1: Default
A2: Hello
第一个构造函数是默认值。然后,您可以看到在第一个A(bool)
调用(引发)之后,进行了复制构造函数调用以返回默认值。第二个调用不会失败,没有复制构造函数调用(由于RVO)。在此之后,您将获得一个默认值A
和一个成功创建的默认值,A
以后可以使用它。
当然,如果复制构造函数也可以抛出该异常,则可能会有异常转义createA
-如果是这种情况,则您必须进行一些修改。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句