它是安全的push_back'动态分配的对象'向量? [英] Is it safe to push_back 'dynamically allocated object' to vector?
问题描述
每当我需要将动态分配的对象添加到向量中时,我一直使用以下方式:
Whenever I need to add dynamically allocated object into a vector I've been doing that the following way:
class Foo { ... };
vector<Foo*> v;
v.push_back(new Foo);
// do stuff with Foo in v
// delete all Foo in v
$
今天,我学习了vector :: push_back可以抛出一个异常。这意味着上面的代码不是异常安全的。 :-(所以我想出了一个解决方案:
Today, I learned vector::push_back can throw an exception. That means the code above is not exception safe. :-( So I came up with a solution:
class Foo { ... };
vector<Foo*> v;
auto_ptr<Foo> p(new Foo);
v.push_back(p.get());
p.release();
// do stuff with Foo in v
// delete all Foo in v
但问题是,新的方式是冗长,乏味,我看到没有人这样做(至少不在我周围...)
But the problem is that the new way is verbose, tedious, and I see nobody's doing it. (At least not around me...)
我应该用新的方式去吗?
或者,我可以只用旧的方式吗?
或者,有更好的方法吗? ?
Should I go with the new way?
Or, can I just stick with the old way?
Or, is there a better way of doing it?
推荐答案
如果你关心的是这个操作的异常安全:
If all you care about is exception-safety of this operation:
v.reserve(v.size()+1); // reserve can throw, but that doesn't matter
v.push_back(new Foo); // new can throw, that doesn't matter either.
释放它的内容指向的对象是一个单独的事情,我相信你会得到大量的建议; - )
The issue of a vector having responsibility for freeing the objects pointed to by its contents is a separate thing, I'm sure you'll get plenty of advice about that ;-)
编辑:嗯,我是报价标准,但我实际上找不到必要的保证。我正在寻找的是 push_back
将不会抛出,除非(a)它必须重新分配(我们知道它不会,因为容量),或者b)T throws的构造函数(我们知道它不会,因为T是一个指针类型)。听起来合理,但是合理!=保证。
hmm, I was going to quote the standard, but I actually can't find the necessary guarantee. What I'm looking for is that push_back
will not throw unless either (a) it has to reallocate (which we know it won't because of the capacity), or (b) a constructor of T throws (which we know it won't since T is a pointer type). Sounds reasonable, but reasonable != guaranteed.
因此,除非在这个问题上有一个有益的答案:
So, unless there's a beneficial answer over on this question:
is std: :vector :: push_back允许抛出由于失败的重新分配或构造之外的任何原因?
这个代码取决于实现不做任何东西imaginative 。没有,你的问题的解决方案可以模板化:
this code depends on the implementation not doing anything too "imaginative". Failing that, your solution from the question can be templated up:
template <typename T, typename Container>
void push_back_new(Container &c) {
auto_ptr<T> p(new T);
c.push_back(p.get());
p.release();
}
用法不太繁琐:
struct Bar : Foo { };
vector<Foo*> v;
push_back_new<Foo>(v);
push_back_new<Bar>(v);
如果它真的是一个工厂函数而不是 new
然后你可以相应地修改模板。在不同的情况下传递很多不同的参数列表将是困难的。
If it's really a factory function rather than new
then you could modify the template accordingly. Passing a lot of different parameter lists in different situations would be difficult, though.
这篇关于它是安全的push_back'动态分配的对象'向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!