如何遵循以下代码
MyClass a(new Foo(), new Bar());
如果“new Foo()”成功,但“new Bar()”抛出,Foo会泄漏吗?
正在服用
std::unique_ptr<Foo>
或
std::shared_ptr<Foo>
作为参数,足以防止泄漏?
答案 0 :(得分:5)
如果“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<>()
)会立即将他们创建的对象关联到相应的智能指针,而不需要这两个操作(动态分配和构建智能指针)与任何其他操作交错。