它是安全的push_back'动态分配的对象'向量? [英] Is it safe to push_back 'dynamically allocated object' to vector?

查看:197
本文介绍了它是安全的push_back'动态分配的对象'向量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我需要将动态分配的对象添加到向量中时,我一直使用以下方式:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆