【发布时间】:2014-03-16 19:51:11
【问题描述】:
我想请教一些关于异常安全的建议。特别是我一直在引用Do you (really) write exception safe code?。如果我有一个指向 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;不是std::vector<Node*> -
哎哟!这看起来很不对劲!
-
当没有任何迹象表明任何东西被推到向量上时,为什么要回滚?如果 new() 抛出一个异常,或者你的 Node 构造函数抛出一个异常(如果有可能它可以抛出)怎么办?
-
@PaulMcKenzie 在除第一次之外的某个迭代中可能不会发生。构造函数可能会抛出 std::bad_alloc 异常。
-
我不明白你的 catch 块做它正在做的事情的原因。如果抛出异常,则不会将任何项目添加到向量中,但您的 catch 块假定此“坏项目”已添加到向量中。
标签: c++ deep-copy exception-safety