版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_39088557/article/details/81532895
std::vector是顺序容器,当用erase成员函数删除一个迭代器指向的元素时,会自动移动(不是std::move)后面的元素到前面来,而迭代器的指向不变(如果是std::map、std::list这类关联型容器,迭代器会失效),并且不会回收内存(也就是capacity不会变)。当用swap成员函数跟自身的拷贝交换时,才能释放多余内存。
代码如下,自定义一个foo类以监视构造、赋值、复制、移动、析构等情况。
#include <iostream>
#include <vector>
class foo{
int a;
public:
foo(int x=0):a(x){std::cout<<a<<" is constructed\n";}
foo(foo &&from){a=std::move(from.a);std::cout<<a<<" is moved\n";}
foo(const foo& from){a=from.a;std::cout<<a<<" is copied\n";}
foo& operator=(const foo&from){
std::cout<<a<<" is assigned by "<<from<<"\n";
if(this == &from)return *this;
a=from.a;
return *this;
}
foo& operator=(foo &&from){
std::cout<<a<<" is move-assigned by "<<from<<"\n";
a=std::move(from.a);
return *this;
}
friend std::ostream &operator<<(std::ostream&o,const foo&f){o<<f.a;return o;}
operator int(){return a;}
~foo(){std::cout<<a<<" is destructed\n";}
};
int main(){
/*1*/std::vector<foo> vec = {0,0,1,2};
std::cout<<"Go through:\n";
std::cout<<"Capacity:"<<vec.capacity()<<std::endl;
for(auto& v:vec) /*printf("%d\n",v);*/std::cout<<v<<std::endl;
std::cout<<"Erase:\n";
for(std::vector<foo>::iterator iter=vec.begin();
/*2*/ iter!=vec.end();/*iter++*/){
if(*iter == 0){
std::cout<<"Erasing:\n";
/*3*/ vec.erase(iter);
std::cout<<"Erased.\n";
}
else/* printf("%d\n",*iter);*/std::cout<<*iter++<<",";
}
std::cout<<"\nGo through again:\n";
std::cout<<"Capacity:"<<vec.capacity()<<std::endl;
for(auto& v:vec) /*printf("%d\n",v);*/std::cout<<v<<std::endl;
std::cout<<"Swapping:\n"<<std::endl;
/*4*/ std::vector<foo>(vec).swap(vec);
std::cout<<"Capacity after swapping:"<<vec.capacity()<<std::endl;
return 0;
}
运行情况如下(在VS 2010 和 VS 2017上跑会出错,在Linux下没问题。不知道为什么这篇文章不能继续加字了。。。