为什么`myvector.push_back(autoPtr.release())`提供强大的异常安全保证?

时间:2010-08-08 00:27:34

标签: c++ boost auto-ptr exception-safe

编辑:我应该提到,我正在查看documentation for Boost's ptr_sequence_adapter,并声称他们的template< class U > void push_back( ::std::auto_ptr<U> x );适配器等同于执行vec.push_back(autoPtr.release());和还提供强有力的例外保证。然后我意识到我混淆了他们对实现效果的描述与实现实际上是什么,所以这个问题是半荒谬的。我只是留在这里为后代。

对我来说,似乎对std::auto_ptr<t>的调用会成功,然后对std::vector<t*>::push_back的调用可能会抛出异常,并且指针会被泄露。

似乎你必须这样做:

vec.push_back(0); //Attempts to allocate space in vector, could throw bad_alloc
vec.back() = autoPtr.release(); //Provides nothrow

2 个答案:

答案 0 :(得分:1)

这是Boost指针容器库的一个特性。

基础push_back成员函数定义为:

void push_back( value_type x )  // strong               
{
    this->enforce_null_policy( x, "Null pointer in 'push_back()'" );

    auto_type ptr( x );           // notrow
    this->base().push_back( x );  // strong, commit
    ptr.release();                // nothrow
}

(来自ptr_sequence_adapter.hpp header

因此,push_back函数本身取得了指针的所有权,如果重新分配失败,它将负责删除指针。

push_back的{​​{1}}重载是根据基本auto_ptr函数定义的:

push_back

指针在调用基类template< class U > void push_back( std::auto_ptr<U> x ) { push_back( x.release() ); } 之前被释放,这是可以的,因为基类push_back函数有很强的保证,如果抛出异常,它将删除指针。

答案 1 :(得分:0)

从auto_ptr中传输对象会释放auto_ptr对对象的控制。它不再受到auto_ptr的好处。您必须将对象放在另一个智能指针中,以便再次成为异常安全,或者是一个容器对象,它提供异常安全保证(如果有的话?)。

请注意,std :: auto_ptr不能直接在STL容器中使用。例如,std :: vector&lt; auto_ptr&lt; int&gt; &GT;会打破。你可以有指向auto_ptrs的指针,并将auto_ptrs存储在其他地方,但是auto_ptr复制语义不会依赖于STL容器,而STL容器依赖于复制。