【问题标题】:c++ exception safety in constructor构造函数中的c ++异常安全
【发布时间】:2013-06-25 16:09:56
【问题描述】:

下面的代码呢

MyClass a(new Foo(), new Bar());

如果“new Foo()”成功了,但是“new Bar()”抛出了,Foo会泄漏吗?

正在服用

std::unique_ptr<Foo>

std::shared_ptr<Foo>

作为参数,足以防止泄露?

【问题讨论】:

    标签: c++ exception c++11 shared-ptr unique-ptr


    【解决方案1】:

    如果“new Foo()”成功了,但是“new Bar()”抛出了,Foo会不会泄露?

    是的。

    是否以[...]为参数,足以防止泄漏?

    不一定。这取决于您如何传递参数。例如,假设您的类构造函数如下所示:

    MyClass::MyClass(std::unique_ptr<Foo> foo, std::unique_ptr<Bar> bar)
    

    以下情况仍可能导致泄漏:

    MyClass a(std::unique_ptr<Foo>(new Foo()), std::unique_ptr<Bar>(new Bar())
    

    这是因为编译器可能被允许按以下顺序计算上述表达式:

    1. 计算表达式new Foo()
    2. 计算表达式new Bar()
    3. 根据 1 的结果构造 std::unique_ptr&lt;Foo&gt; 临时。
    4. 根据 2 的结果构造 std::unique_ptr&lt;Bar&gt; 临时。

    如果 2) 引发异常,则您的 Foo 已丢失。

    但是,可以使用 std::make_unique&lt;&gt;()(仅限 C++14)或 std::make_shared&lt;&gt;() 来确保安全,如下所示:

    MyClass a(std::make_unique<Foo>(), std::make_unique<Bar>());
    

    现在不可能发生泄漏,因为std::make_unique&lt;&gt;()(和std::make_shared&lt;&gt;())会立即将它们创建的对象与相应的智能指针相关联,而这两个操作(动态分配和智能指针的构造)不会与任何其他操作。

    【讨论】:

    • @DarioOO:很高兴它有帮助:)
    • @DarioOO:C++ 委员会说在 C++11 标准中不包括 make_unique 是因为他们只是忘记了。与make_shared相比,它的编写极其简单,因此他们认为程序员会自己编写它。我认为他们专注于 make_shared,与手动 shared_ptr 构造相比,它试图提高性能。
    • 是的,我认为 make_shared 的主要优势只是性能提升,但阅读这个答案不仅仅是简单的性能提升。
    猜你喜欢
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 2014-02-01
    相关资源
    最近更新 更多