5

我目前正在让自己进入 c++ 以使用 opengl 进行较低级别的编码。我来自一个沉重的 objc 背景,所以我对内存管理有一些了解,但我似乎无法理解“boost”库如何管理容器类型,如ptr_vector.

我认为我的问题与我不知道如何ptr_vector管理自身及其对象的破坏有关。

请看下面的代码:

// Header file
...
ptr_vector<IObject3D> objects;
...

// Implementation file
...
void ApplicationEngine::init()
{
    WavefrontObject3D *object = new WavefrontObject3D("Ninja.obj");
    objects.push_back(object); 
}
...

那么,对于实际的问题:我是否通过“对象”变量在这里创建了泄漏?

我习惯于使用 objc 中的显式调用手动保留和释放我的对象:以前我必须alloc init将 WavefrontObject3Dobject添加到数组中,然后再添加release同一个对象以避免泄漏。

但是当我delete object在调用之后添加一个push_backWavefrontObject3D 的解构函数时object被调用。这给了我一个提示,即ptr_vector没有保留object变量。我的假设正确吗?

附加但相关的问题:假设我想销毁包含类ApplicationEngine,我是否必须在它管理的元素上调用某种解构器ptr_vector

4

4 回答 4

6

不,这不会造成泄漏。ptr_*当容器超出范围时,所有容器都会删除存储在其中的对象。

如果在将对象添加到容器后删除它,您将创建undefined behavior容器将尝试再次删除它。

附加问题:不,如果您存储ptr_vector按值,它的生命周期由周围类的范围管理。

让我们写一个简单的实现ptr_vector。它不支持间接迭代器和自定义删除器以及许多其他东西,但显示了使用的原则。

template <typename T>
class ptr_vector {
public:
  // assume control over it
  void push_back(T* x) 
  { if(x) c_.push_back(x); else throw bad_pointer(); }

  ~ptr_vector() { 
    // delete everything that is stored here
    for(auto x : c_)  delete x;
  }
private:
  std::vector<T*> c_;
};


// a user class
struct user_class {
  void addSomething() { x.push_back(new int(23)); }
  ptr_vector<int> x;
};

如果用户类超出范围,ptr_vector将调用析构函数并回收所有内存。看不到泄漏。

于 2012-07-26T09:20:48.160 回答
2
void push_back( T* x );

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

template
    < 
        class T, 
        class CloneAllocator = heap_clone_allocator,
        class Allocator      = std::allocator<void*>
    >
    class ptr_vector : public ptr_sequence_adapter
                              <
                                  T,
                                  std::vector<void*,Allocator>,
                                  CloneAllocator
                              >

所以你可以指定你自己的CloneAllocator而不是删除存储在 ptr_vector 中的元素,但是heap_clone_allocator(默认 par for CloneAllocator)删除析构函数中的所有存储元素。

http://www.boost.org/doc/libs/1_50_0/libs/ptr_container/doc/reference.html#class-heap-clone-allocator

于 2012-07-26T09:19:37.383 回答
0

ptr_vector将释放其析构函数中的所有元素,因此您无需做任何已经做的事情,即创建对象,将它们添加到 中ptr_vector,然后将管理留给它。显式调用delete将使对象被销毁两次(一次是在您请求它时,一次是在ptr_vector完成时)。换句话说,ptr_vector不复制对象。

完成ApplicationEngine后,如果它有 的实例,ptr_vector则将调用该向量的析构函数,进而删除添加的对象。

于 2012-07-26T09:18:42.687 回答
0

ptr_containers拥有您传递给它的指针所指向的内存。 阅读文档以获取有关可克隆概念的更多信息。

于 2012-07-26T09:24:08.867 回答