简体   繁体   中英

c++ exception safety in constructor

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:

  1. Evaluate the expression new Foo()
  2. Evaluate the expression new Bar()
  3. Construct the std::unique_ptr<Foo> temporary from the result of 1.
  4. Construct the 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM