1

Boost Pointer Container的第一个示例添加了一个指向结构的原始指针:

class zoo
{
    boost::ptr_vector<animal> the_animals;
public:

    void add_animal( animal* a )
    {
        the_animals.push_back( a );
    }
};

但是如果push_back或任何其他可能触发重新分配的成员函数在此过程中抛出异常怎么办?据我了解,在这种情况下,由调用者来管理给定对象的内存,但是由于调用者将原始指针传递给旨在管理内存的类,因此调用者很可能不会吨。

那么,是否不需要在上面的代码示例中使用某种唯一的智能指针来包装指针,然后再将其提供给容器并确保没有内存泄漏?容器确实为此类智能指针提供了重载,但它们不会强制使用它们。

或者是容器在任何添加操作期间根本不会抛出异常并且它总是成功的论点?

4

1 回答 1

1

如果您使用std::vector<animal*>而不是boost::ptr_vector<animal>. Boost.PointerContainer 旨在处理指向需要释放的资源的指针,因此您不必担心这些事情。

Boost 文档为各种成员函数提供异常安全保证。ptr_vector继承push_backptr_sequence_adaptor, 并列出了push_backas

void push_back( T* x );

要求:x != 0
效果: 将指针插入容器并获得它的所有权
抛出:bad_pointerifx == 0
异常安全: 强保证

The strong guarantee means that if push_back throws, the state of the container is rolled back to what it was immediately prior to the call to push_back and no resource is leaked. Now, you could argue that that doesn't guarantee anything about the resource you were trying to add to the container, but it would be very bad form on the part of the implementation to allow that resource to leak, especially since the call to push_back is supposed to take ownership of the object being passed by the caller.

If we look at the implementation of push_back, it shows how ptr_vector guarantees that the resource you're trying to add is not leaked.

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
}

So an auto_type is first constructed prior to the actual push_back operation being attempted. A bit more digging around reveals that auto_type is an alias for static_move_ptr, which is a smart pointer type that will, when necessary, free the resource it owns upon destruction.

Thus, in the example shown, the animal * you're trying to add will never be leaked, even if an exception is thrown.

于 2015-05-21T17:08:31.647 回答