异常安全:
Exception safety:
我想征求一些关于异常安全的建议。特别是我一直在引用你(真的)写异常安全代码吗?如果我有一个指向类型为Node
的对象的指针容器,并且我要用一个新的对象集合清除和重新初始化该对象容器_nodes
,这段代码是否异常安全?
std::vector<Node*> nodes;
for (int i = 0; i < 10; i++)
{
try
{
// New can throw an exception. We want to make sure that if an exception is thrown any allocated memory is deleted.
std::unique_ptr<Node> node(new Node());
Node* n = node.get();
nodes.push_back(n);
node.release();
}
catch (std::exception& exception)
{
// If an exception is thrown, rollback new allocations and rethrow the exception.
for (std::vector<Node*>::iterator it = nodes.begin(); it < nodes.end(); it++)
{
delete *it;
}
nodes.clear();
throw exception;
}
}
_nodes.swap(nodes);
// Delete the unused (previous) objects from the swapped container.
for (std::vector<Node*>::iterator it = nodes.begin(); it < nodes.end(); it++)
{
delete *it;
}
我也一直在阅读RAII,但我不知道这将如何工作,我需要多态性(http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping)。
这比它需要的要复杂得多。我将这样开始:
std::vector<std::unique_ptr<Node>> nodes(10);
for (auto& p : nodes)
p.reset(new Node());
如果构造向量或分配Node
抛出,则所有内容将自动清理。
现在,如果你是明智的,用std::vector<std::unique_ptr<Node>>
替换_nodes
,那么剩下的功能是简单的:
_nodes.swap(nodes);
否则就不那么简单了:
std::vector<Node*> nodes2;
nodes2.reserve(nodes.size());
for (auto p : nodes)
nodes2.push_back(p.release());
_nodes.swap(nodes2);
for (auto p : nodes2)
delete p;
假设Node
析构函数不能抛出,这里唯一可以抛出的步骤是reserve
调用,所以如果抛出nodes
就会被清理,因为它持有unique_ptr
对象。之后,您可以安全地将所有权转移到nodes2
,然后交换,然后清理。
我也一直在阅读RAII,但我不知道这将如何工作,我需要多态性
我上面的代码依赖于RAII,多态性是无关紧要的。上面的代码中没有不属于RAII类型的原始指针(_nodes
除外,您应该将其更改为std::vector<std::unique_ptr<Node>>
),因此如果抛出异常,则所有内容都将被清理,无需捕获异常并进行手动清理。
相关文章:
- C++代码中的异常安全
- 编写"anti-lack of memory"异常安全代码
- std:string::substr 异常安全吗?
- 如何以异常安全的方式使用放置新?
- 通过引用从 c++ 函数异常返回对象是否安全
- 异常安全服务器
- 实现 std::vector::p ush_back 强异常安全
- 标准::unique_ptr和异常安全
- 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全
- 使功能异常安全
- 与构造函数参数相关的异常安全的习语
- uninitialized_copy() 异常安全吗?
- 为什么我们需要 RAII 来解决异常安全问题
- 异常安全构造函数
- 关于 swap() 操作的异常安全 - 这有什么问题?
- std::vector::擦除异常安全
- 异常安全 - 用于可靠回滚对象状态的模式
- 异常安全的 for 循环
- 异常安全代码和移动语义
- 向量::插入的异常安全保证是什么?