构造函数中的c++异常安全
c++ exception safety in constructor
下面的代码怎么样
MyClass a(new Foo(), new Bar());
如果"new Foo()"成功,但"new Bar()"抛出,Foo会泄漏吗?
正在进行
std::unique_ptr<Foo>
或
std::shared_ptr<Foo>
作为参数,是否足以防止泄漏?
如果"new Foo()"成功,但"new Bar()"抛出,Foo会泄漏吗?
是的。
以[…]为参数是否足以防止泄漏?
不一定。这取决于如何传递参数。例如,即使假设你的类构造函数是这样的:
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())
这是因为编译器可能被允许按以下顺序评估上述表达式:
- 对表达式
new Foo()
求值 - 对表达式
new Bar()
求值 - 根据1的结果构造临时
std::unique_ptr<Foo>
- 根据2的结果构造
std::unique_ptr<Bar>
临时
如果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++代码中的异常安全
- 编写"anti-lack of memory"异常安全代码
- std:string::substr 异常安全吗?
- 如何以异常安全的方式使用放置新?
- 异常安全服务器
- 实现 std::vector::p ush_back 强异常安全
- 标准::unique_ptr和异常安全
- 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全
- 使功能异常安全
- 与构造函数参数相关的异常安全的习语
- uninitialized_copy() 异常安全吗?
- 为什么我们需要 RAII 来解决异常安全问题
- 异常安全构造函数
- 关于 swap() 操作的异常安全 - 这有什么问题?
- std::vector::擦除异常安全
- 异常安全 - 用于可靠回滚对象状态的模式
- 异常安全的 for 循环
- 异常安全代码和移动语义
- 向量::插入的异常安全保证是什么?
- 异常安全和make_unique