c++ - 如何从 C++ 中的构造函数中捕获异常

标签 c++ exception

假设我们有一个可能会抛出异常的构造函数。

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 block 中。

最佳答案

您可以定义一个创建函数来为您处理异常,并在发生异常时返回一个合理的默认值,例如:

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 - 如果是这种情况,您将不得不稍微修改此设计。

关于c++ - 如何从 C++ 中的构造函数中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38395879/

相关文章:

c++ - 将第一个值插入链表时尝试访问头部时出现段错误

java - java中的FileNotFoundException

python - 了解 Python 中的异常处理

java - 这个 "NoSuchMethod"异常中缺少哪个方法?

c++ - 为什么我输入的数字只能读到6位有效数字?

c++ - qt中有QRect的3D类比吗?

c++ - 如何使用 std :fill 设置 C 数组特定范围的值

java - 在封闭类之外调用扫描仪对象时如何关闭它?

java - 故意抛出异常是一种不好的形式吗?

c++ - 在类中定义的友元函数的完全限定名称是什么?