c++ - push_back 'dynamically allocated object' 到 vector 安全吗?

标签 c++ vector exception-safe

每当我需要将动态分配的对象添加到一个 vector 中时,我都会按照以下方式进行操作:

class Foo { ... };

vector<Foo*> v;

v.push_back(new Foo);

// do stuff with Foo in v

// delete all Foo in v

它刚刚奏效,许多其他人似乎也在做同样的事情。

今天,我了解到 vector::push_back 可以抛出异常。这意味着上面的代码不是异常安全的。 :-( 所以我想出了一个解决方案:

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

但问题是新方法冗长乏味,而且我看没有人这样做。 (至少不在我身边……)

我应该走新路吗?
或者,我可以继续使用旧方法吗?
或者,有更好的方法吗?

最佳答案

如果您只关心此操作的异常安全性:

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.

负责释放其内容指向的对象的 vector 问题是另一回事,我相信您会得到很多关于这个的建议 ;-)

编辑:嗯,我本来是要引用标准的,但我实际上找不到必要的保证。我正在寻找的是 push_back 不会抛出,除非 (a) 它必须重新分配(我们知道它不会因为容量),或 (b) T 的构造函数抛出(我们知道它不会因为 T 是指针类型)。听起来合理,但合理!=保证。

所以,除非对这个问题有一个有益的答案:

Is std::vector::push_back permitted to throw for any reason other than failed reallocation or construction?

这段代码取决于实现,没有做任何太“富有想象力”的事情。如果做不到这一点,您可以将问题的解决方案模板化:

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 那么您可以相应地修改模板。不过,在不同的情况下传递大量不同的参数列表会很困难。

关于c++ - push_back 'dynamically allocated object' 到 vector 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4185350/

相关文章:

c++ - 使用 Boost Spirit 解析语法

c++ - 寻找与另一个相反的 vector ?

ios - 将相机朝它指向的方向移动,同时考虑到旋转

c++ - `myvector.push_back(autoPtr.release())`为什么提供强异常安全保障?

c++ - 读取 header ,CURL

C++访问冲突崩溃

c++ - 在向 vector 添加更多元素之前引用 vector 元素

c++ - unique_ptr<>() 初始化会失败吗?

terminology - 如何描述一个在执行过程中抛出异常时不会产生副作用的方法?

c++ - 类定义中的段错误无法找出位置