vector的所有函数和使用的注意事项

时间:2022-06-01 16:21:38

1、构造函数:

       (1)vector<> v;默认构造函数

       (2)vector<> v1(v)或v1=v;拷贝构造函数

       (3)vector<> v2(v.begin(),v.end());用迭代器作为参数

       (4)vector<> v3(n);用n指出对象个数

       (5)vector<> v4(n,t);初始化n个对象,每个对象用t初始化

       (6)vector<> v5{}或v5={};用初始化列表初始化,这是C++11标准,VS2010不可以

2、assign函数:(只有顺序容器有)

assign函数可以对已有容器进行重新赋值,可以改变原来容器的size和capacity。构造函数只能用相同容器类型和相同元素类型进行初始化,而assign可以用不同的容器类型和元素类型,只要元素可以进行隐式类型转换即可。assign后会使当前调用assign的容器的迭代器失效。

3、at函数:

       at函数用来访问容器中下标为i的元素,此时如果越界,则会抛出out-of-range异常,而普通的下标访问[]不会抛出异常,会引起运行时错误。

4、back和front函数:

       back返回容器最后一个元素的引用,front返回容器第一个元素的引用。注意此时要保证容器是非空的。

5、begin,cbegin,rbegin,end,cend,rend:

       返回迭代器,其中cbegin返回const迭代器,rbegin返回容器最后一个元素的迭代器,注意不是end,而rend返回第一个元素前面的迭代器,rbegin++相当于--end。其它类似。

6、capacity和reserve,size和resize:

       capacity()是表示当前容器最多能存放多少元素而不重新开辟空间,reserve()表示要对当前容器预留多少元素,其改变的是capacity,如果reserve(n),n比原来的capacity大,则重新分配空间,如果小,则不重新分配,capacity也不改变。

       size()返回当前容器中的元素个数,resize(n,t)会改变size,如果n比size大,则剩下的部分用元素t来填充,如果小,则直接删除掉多余的元素,调用resize()增大size后有可能会是capacity变化。删除元素后,如果原来迭代器在删除的元素个数之前,迭代器不失效,如果迭代器指向n以后的元素,迭代器失效n小时,resizecapacity是不一样的

<span style="white-space:pre"></span>vector<int> v;
v.reserve(20);
v.assign(10,2);
cout<<v.capacity()<<endl;
v.resize(21);
cout<<v.size()<<endl;
cout<<v.capacity()<<endl;

7、clear函数:

       清空所有元素。

8、data函数:

       返回当前容器的首元素指针,此时对于顺序容器可以直接用指针进行操作了。

9、emplace()和emplace_back()函数,insert函数

       emplace函数在制定迭代器前面插入一个元素,emplace_back()在容器最后插入一个元素,这个函数和push_back函数不同,push_back函数只能传入已经构建好的对象,或者是临时对象,容器中存放的是这个对象或者临时对象的拷贝版本,因此会调用拷贝构造函数,如果是临时对象,则会先调用构造函数创建一个临时对象,然后进行拷贝构造函数构建临时对象的拷贝版本放入容器中,因此会调用一次构造函数,一次析构函数(用于将临时对象析构)和一次拷贝构造函数。而emplace能够接受参数列表,直接将构造的对象放入到容器中。如果emplace接收的参数也是一个对象,则仍让放入这个对象的拷贝版本,此时和push_back函数时一样的。

         vector<int>v;
v.reserve(100);
v.assign(10,2);
autoiter1=v.begin()+3;
autoiter2=v.begin()+5;
autoiter3=iter2+2;
v.emplace(v.begin()+5,4);//v.insert(v.begin()+5,1,4);就会使后面迭代器失效,此处iter2和iter3失效
v.insert(v.begin()+5,4);
cout<<*iter1<<endl;
cout<<*iter2<<endl;
cout<<*iter3<<endl;

emplace(iter,t) insert(iter,t) 只有 vector 容器空间足够,都不会改变迭代器,但是用 insert(iter,n,t) 就会使插入元素及其后面的迭代器失效。而对于 deque 来说,除了在首尾位置插入外,其他地方插入都会使迭代器失效!!

       同样emplace_back在不改变容器capacity的情况下所有迭代器都有效

       注意deque没有capacity函数,因为其实动态分配内存,且内存不一定连续,里面维护这一个指针数组。

10、empty函数:

       返回bool类型,判断容器是否为空。

11、erase函数:

       删除制定迭代器位置的元素,或者删除由两个迭代器制定的区间的元素。删除位置的迭代器和其后的迭代器都失效

12、max_size函数:

       返回容器最多能够容纳的对象个数,VS2010中是1073741823,即2^30。

13、push_back和pop_back函数:

       push_back()和pop_back()函数会使end迭代器失效,即插入位置和删除位置的迭代器会失效。

14、shrink_to_fit函数:

       将capacity缩减至size大小,但是,具体的实现可以选择忽略此请求,也就是说,调用shrink_to_fit也并不保证一定退回内存空间。

15、swap函数:

       array外,swap不对任何顺序容器的元素进行拷贝、删除或插入操作,因此可以保证在常数时间内完成。除string外,指向容器的迭代器、引用和指针在swap操作以后多不会失效。它们仍然指向swap操作之前所指向的那些元素,只是在swap后,这些元素已经属于不同容器了。对于一个string调用swap会导致迭代器、引用和指针失效。

       swap两个array会真正交换它们的元素。因此交换两个array所需要的时间与array中元素数目成正比

         

<span style="white-space:pre"></span>vector<int>v;
v.assign(10,2);
autoiter1=v.begin()+3;
vector<int>v2;
v2.assign(10,3);
autoiter2=v2.begin()+3;
swap(v,v2);
cout<<*iter1<<" "<<*iter2<<endl;

string s1="11111111";
string s2="22222222";
autoiter3=s1.begin()+2;
autoiter4=s2.begin()+2;
swap(s1,s2);
cout<<*iter3<<" "<<*iter4<<endl;//出错,不能访问