构造函数中的c++异常安全

标签 c++ exception c++11 shared-ptr unique-ptr

下面的代码呢

MyClass a(new Foo(), new Bar());

如果“new Foo()”成功,但“new Bar()”抛出,Foo 会泄漏吗?

正在服用

std::unique_ptr<Foo>

std::shared_ptr<Foo>

作为参数,足以防止泄漏?

最佳答案

if "new Foo()" is successful, but "new Bar()" throws, does Foo will leak?

是的。

Is taking [...] as parameters, enough to prevent the leak?

不一定。这取决于你如何传递参数。例如,即使假设您的类构造函数看起来像这样:

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())

这是因为允许编译器按以下顺序计算上述表达式:

  1. 计算表达式 new Foo()
  2. 计算表达式 new Bar()
  3. 构建 std::unique_ptr<Foo>临时从 1 的结果。
  4. 构建 std::unique_ptr<Bar>临时从 2 的结果。

如果 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<>() )立即将他们创建的对象与相应的智能指针相关联,而这两个操作(智能指针的动态分配和构造)不会与任何其他操作交错。

关于构造函数中的c++异常安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17355331/

相关文章:

c# - 新的 .NET 运行时能否抛出更有意义的空引用异常?

c++ - 静态模板成员函数的实例化?

c++ - 在字符串 vector 中查找字母数 C++

c++ - 返回 static_cast<int> C++ 和 C

android - 尝试捕捉 : Is it OK to leave applications with handled exceptions?

java - PHP exec() 不接受 java 类路径

C++ 字符串文字和常量

c++ - 我还应该在 C++11 中返回 const 对象吗?

c++ - 虚函数无法显示正确的结果

c++ - 如何将gsl添加到MinGW?