[英]Does ptr_vector iterator not require increments?
#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循环不会增加迭代器,但是会迭代并擦除所有元素。 我的问题是:
- 我的迭代技术和使用迭代器是否正确?
- 如果在for循环中不需要迭代器增量,那么增量在哪里发生?
- 使用迭代器会更好还是使用一个普通的整数就足够了(即:使用迭代器会带来任何附加值)吗? (因为我还可以擦除第5个元素,例如pv.erase(pv.begin()+ 5);)
- 有什么方法可以直接将新对象分配给ptr_vector的特定位置(假设是第5个位置)? 我正在寻找类似pv [5] = new Derived(5);的东西。 有什么办法吗?
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
。 指针向量将在您向其分配新值的索引处调用对象的赋值运算符。
我的迭代技术和使用迭代器是否正确?
不,从容器中擦除通常会使迭代器对被擦除的项目无效。 如果可行,这只是实现细节的副作用。
正确的方法是使用擦除方法的返回值:
it = pv.erase(it);
但是,要清空容器,可以使用clear成员函数。
如果在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);
但这只会修改存储的对象,不会更改指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.