What about following code
MyClass a(new Foo(), new Bar());
if "new Foo()" is successful, but "new Bar()" throws, will Foo leak?
Is taking
std::unique_ptr<Foo>
or
std::shared_ptr<Foo>
as parameters, enough to prevent the leak?
if "new Foo()" is successful, but "new Bar()" throws, does Foo will leak?
Yes.
Is taking [...] as parameters, enough to prevent the leak?
Not necessarily. It depends on how you pass the parameters. For instance, even supposed your class constructor looks like this:
MyClass::MyClass(std::unique_ptr<Foo> foo, std::unique_ptr<Bar> bar)
The following may still cause a leak:
MyClass a(std::unique_ptr<Foo>(new Foo()), std::unique_ptr<Bar>(new Bar())
That is because the compiler may is allowed to evaluate the above expressions in the following order:
new Foo()
new Bar()
std::unique_ptr<Foo>
temporary from the result of 1. std::unique_ptr<Bar>
temporary from the result of 2. If 2) throws an exception, you've lost your Foo
.
However, it is possible to make this safe by using std::make_unique<>()
(C++14 only) or std::make_shared<>()
, like so:
MyClass a(std::make_unique<Foo>(), std::make_unique<Bar>());
Now no leak could possibly happen, because std::make_unique<>()
(and std::make_shared<>()
) immediately associate the object they create to the corresponding smart pointer, without these two operations (dynamic allocation and construction of the smart pointer) being interleaved with any other operation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.