【发布时间】: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
下面的代码呢
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
如果“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())
这是因为编译器可能被允许按以下顺序计算上述表达式:
new Foo()
new Bar()
std::unique_ptr<Foo> 临时。std::unique_ptr<Bar> 临时。如果 2) 引发异常,则您的 Foo 已丢失。
但是,可以使用 std::make_unique<>()(仅限 C++14)或 std::make_shared<>() 来确保安全,如下所示:
MyClass a(std::make_unique<Foo>(), std::make_unique<Bar>());
现在不可能发生泄漏,因为std::make_unique<>()(和std::make_shared<>())会立即将它们创建的对象与相应的智能指针相关联,而这两个操作(动态分配和智能指针的构造)不会与任何其他操作。
【讨论】:
make_unique 是因为他们只是忘记了。与make_shared相比,它的编写极其简单,因此他们认为程序员会自己编写它。我认为他们专注于 make_shared,与手动 shared_ptr 构造相比,它试图提高性能。