ptr_vector迭代器不需要增量吗?

时间:2010-10-23 09:25:44

标签: c++ boost ptr-vector

#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
using namespace std;

class Derived
{
public:
        int i;
        Derived() {cout<<"Constructed Derived"<<endl;}
        Derived(int ii):i(ii) {cout<<"Constructed Derived"<<i<<endl;}
        ~Derived() {cout<<"* Destructed Derived"<<i<<endl;}
};

int main()
{
   boost::ptr_vector<Derived> pv;
   for(int i=0;i<10;++i) pv.push_back(new Derived(i));

   boost::ptr_vector<Derived>::iterator it;
   for (it=pv.begin(); it<pv.end();/*no iterator increment*/ )
        pv.erase(it);
   cout<<"Done erasing..."<<endl;
}

请注意,第二个for循环不会递增迭代器,但它会迭代并擦除所有元素。我的问题是:

  
    
      
        
          
              
  1. 我的迭代技术和使用迭代器是否正确?
  2.           
  3. 如果for循环中不需要迭代器增量,那么增量发生在哪里?
  4.           
  5. 使用迭代器或者普通的整数是否更好(即:使用迭代器是否有任何增值)? (因为我也可以删除第5个元素,如pv.erase(pv.begin()+ 5);)
  6.           
  7. 有没有办法直接将新对象分配到ptr_vector的特定位置(比如第5位)?我正在寻找类似pv [5] = new Derived(5);的东西。这样做的任何方式?
  8.                    
      
    
  

2 个答案:

答案 0 :(得分:3)

ptr_vector::iterator增量就像普通的随机访问迭代器一样。在您的示例中,您可以擦除每个元素而不实际递增,因为在擦除元素之后,其后的每个元素都会在数组中移动。因此,当您擦除第0个元素时,您的迭代器现在指向使用作为第1个元素的元素,但现在是第0个元素,依此类推。换句话说,当整个向量向左移动时,迭代器保持在原位。

这与ptr_vector没有任何关系。请注意,普通std::vector会发生相同的行为。

另请注意,在擦除指向的元素后使用迭代器是危险的。在你的情况下它是有效的,但最好采用ptr_vector::erase的返回值,这样你就得到一个保证有效的新迭代器。

 for (it = pv.begin(); it != pv.end(); )
        it = pv.erase(it);

至于你的其他问题:

如果您只想删除特定元素,那么您当然应该使用pv.erase(pv.begin() + N)直接删除它。要为指针向量中的特定元素指定新值,只需说出pv[N] = Derived(whatever)。重新分配值时,您无需使用new。指针向量将在您为其赋值的索引处调用对象的赋值运算符。

答案 1 :(得分:1)

  

我的迭代技术和使用迭代器是否正确?

不,从容器中删除通常会使删除项的迭代器无效。如果它有效,这只是实现细节的副作用。

正确的方法是使用erase方法的返回值:

 it = pv.erase(it);

但是,要清空容器,可以使用clear member函数。

  

如果for循环中不需要迭代器增量,那么在哪里   增量是否会发生?

它不会发生,因为你总是会删除容器中的第一个项目(偶然,可能无法与其他容器一起使用)。

  

使用迭代器或普通整数是否更好(即:   使用时是否有任何增值功能   迭代器)? (因为我也可以删除   第5个元素   pv.erase(pv.begin()+5);

在随机访问容器中,您可以这样做,否则不能(例如列表)。

  

有没有办法将新对象分配到特定位置(让我们   说ptr_vector的第5个位置,   直?我正在寻找一些东西   比如pv[5]=new Derived(5);。无论如何   这样做?

根据提升参考:

pv.replace(5, new Derived(5));

这将返回智能指针中的现有指针,因此它将自动释放。 (很奇怪这需要一个索引,而不是一个迭代器......)。

或者:

pv[5] = Derived(5);

但这只会修改存储的对象,而不是更改指针。