2010-10-23 72 views
2
#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循环不会递增迭代器,但它会迭代和删除所有元素。我的问题是:ptr_vector迭代器不需要增量吗?

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

回答

1

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

不,从容器中擦除通常会使迭代器无效到已擦除项目。如果有效,这只是实施细节的副作用。

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

it = pv.erase(it); 

然而,排空容器,可以用清晰的成员函数。

如果不需要迭代增量的for循环,然后在那里 没有增量发生?

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

是更好地使用迭代器或将一个普通的整数就足够了(即: 有任何增值使用 迭代器)? (怎么我还可以删除像 pv.erase(pv.begin()+5);的 第五元素)

在一个随机存取容器,你能做到这一点,否则没有(如表)。

有什么办法到一个新的对象分配给ptr_vector的特定位置(让我们 说,第5位), 直接?我在找东西 ,比如pv[5]=new Derived(5);。任何方式 这样做?

依据升压参考:

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

这个方法返回一个智能指针现有的指针,所以它会自动释放。 (奇怪的是,这需要一个索引,而不是迭代器......)。

或者:

pv[5] = Derived(5); 

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

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。指针向量将调用指定新值的索引处的对象的赋值运算符。

+0

很酷!希望能回答问题3和4 :) – Nav 2010-10-23 09:59:19

+0

没有。我试过PV [0] =派生(888);并获得此输出:构造Derived888 boostPtrVsSTL:/usr/include/boost/ptr_container/ptr_sequence_adapter.hpp:325:typename boost :: ptr_container_detail :: reversible_ptr_container ,CloneAllocator>: :引用boost :: ptr_sequence_adapter :: :: operator [](typename boost :: ptr_container_detail :: reversible_ptr_container Nav 2010-10-23 10:06:50

+0

[continue ...],CloneAllocator> size_type)[with T = Derived,VoidPtrSeq = std :: vector >,CloneAllocator = boost :: heap_clone_allocator]:断言'n < this-> size()'失败。 Aborted(核心转储) – Nav 2010-10-23 10:07:20