c++ exception safety in constructor

心已入冬 提交于 2019-12-08 21:38:34

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/17355331/c-exception-safety-in-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!