Boost Pointer Container的第一个示例添加了一个指向结构的原始指针:
class zoo
{
boost::ptr_vector<animal> the_animals;
public:
void add_animal( animal* a )
{
the_animals.push_back( a );
}
};
但是如果push_back
或任何其他可能触发重新分配的成员函数在进程中抛出异常怎么办?根据我的理解,在这种情况下,由调用者来管理给定对象的内存,但是因为调用者将一个原始指针传递给一个用于管理内存的类,所以调用者很可能不会吨。
那么,在上面的代码示例中是否需要使用某种独特的智能指针来包装指针,然后再将其提供给容器并且绝对确保没有内存泄漏?容器确实为这些智能指针提供了过载,但它们并没有强制使用它们。
或者说容器在任何添加操作期间根本不会抛出异常并且它总是成功吗?
答案 0 :(得分:1)
如果您使用的是std::vector<animal*>
而不是boost::ptr_vector<animal>
,那么您所关注的问题非常有效。 Boost.PointerContainer旨在处理需要释放的资源的指针,因此它不必担心这些事情。
Boost文档为各种成员函数提供了异常安全保证。 ptr_vector
从ptr_sequence_adaptor
继承push_back
,并将push_back
的行为列为
void push_back( T* x );
要求:
x != 0
效果:将指针插入容器并获得它的所有权 如果bad_pointer
,则抛出x == 0
例外安全:有力保证
strong guarantee表示如果push_back
抛出,则容器的状态将回滚到调用push_back
之前的状态,并且没有资源泄露。现在,您可以争辩说,这并不能保证您尝试添加到容器中的资源,但是在实现方面允许该资源泄漏的形式非常糟糕,尤其是在调用之后to push_back
应该取得调用者传递的对象的所有权。
如果我们查看push_back
的{{3}},则会显示ptr_vector
如何保证您尝试添加的资源不会泄露。
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
}
因此,在尝试实际的auto_type
操作之前首先构造push_back
。更多的挖掘表明auto_type
是implementation的别名,它是一种智能指针类型,必要时将释放它在破坏时拥有的资源。
因此,在显示的示例中,即使抛出异常,您尝试添加的animal *
也不会泄露。