6

下面的代码呢

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

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

正在服用

std::unique_ptr<Foo>

或者

std::shared_ptr<Foo>

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

4

1 回答 1

6

如果“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<Foo>临时变量。
  4. 根据 2 的结果构造std::unique_ptr<Bar>临时变量。

如果 2) 引发异常,则您丢失了Foo.

但是,可以通过使用std::make_unique<>()(C++14 only) or来确保安全std::make_shared<>(),如下所示:

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

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

于 2013-06-28T00:25:26.850 回答