if "new foo ()" succeeds but the "new bar ()" throws, will foo not leak?
Yes.
Takes [...] as parameters sufficient to prevent leakage?
Not necessary. It depends on how you pass the parameters. For example, even the intended constructor of a class is as follows:
MyClass::MyClass(std::unique_ptr<Foo> foo, std::unique_ptr<Bar> bar)
The following may still cause leakage:
MyClass a(std::unique_ptr<Foo>(new Foo()), std::unique_ptr<Bar>(new Bar())
This is because the compiler is allowed to evaluate the above expressions in the following order:
- Evaluate expression
new Foo() - Rate the expression
new Bar() - Create a
std::unique_ptr<Foo> temporary result from the result. - Build temporary
std::unique_ptr<Bar> from result 2.
If 2) throws an exception, you have lost Foo .
However, this can be done using std::make_unique<>() (only for C ++ 14) or std::make_shared<>() , for example:
MyClass a(std::make_unique<Foo>(), std::make_unique<Bar>());
Now the leak cannot happen, because std::make_unique<>() (and std::make_shared<>() ) immediately connect the created object with the corresponding smart pointer, without these two operations (dynamic allocation and construction of the smart pointer), alternating with any other operation.
source share