vector底層是一個動态數組,包含三個疊代器,start和finish之間是已經使用的空間範圍,end_of_storage是整塊連續空間包括備用空間的尾部。
vector記憶體增長機制:當空間不夠裝下資料時,會自動申請另一片更大的空間,大小為原來的兩倍,然後把原來的資料拷貝到新的記憶體空間,接着釋放原來的空間。
當删除資料的時候,存儲空間不釋放,隻是清空裡面的資料。
是以,對vector的操作一旦引擎了空間的重新配置,指向原vector的所有疊代器都失效。
(2)vector中的reserve和resize的差別
vector中reserve和resize的差別:
reserve是直接擴充到已經确定的大小,減少多次開啟、釋放空間。
resize()可以改變空間的大小,也有改變預設值的功能,capacity的大小也會随着改變。
(3)vector中的size和capacity的差別
size表示目前vector中有多少個元素(finish - start),而capacity函數則表示它已經配置設定的記憶體中可以容納多少元素(end_of_storage - start)。
(4)vector的元素類型可以是引用嗎?
vector的底層實作要求連續的對象排列,引用并非對象,沒有實際位址,是以vector的元素類型不能是引用。
(5)vector疊代器失效的情況
當插入一個元素到vector中,由于引起了記憶體重新配置設定,是以指向原記憶體的疊代器全部失效。
當删除容器中一個元素後,該疊代器所指向的元素已經被删除,那麼也造成疊代器失效。erase方法會傳回下一個有效的疊代器,是以當我們要删除某個元素時,需要it=vec.erase(it);。
(6)正确釋放vector的記憶體(clear(), swap(), shrink_to_fit())
vec.clear():清空内容,但是不釋放記憶體。
vector().swap(vec):清空内容,且釋放記憶體,相當于得到一個全新的vector。
vec.shrink_to_fit():請求容器降低其capacity和size比對。
vec.clear();vec.shrink_to_fit();:清空内容,且釋放記憶體。
實踐代碼:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename T>
void coutall(vector<T> &vct)
{
//使用auto,請確定編譯器支援C++11
for(auto it = vct.begin();it != vct.end();it++)
{
cout<< *it << " ";
}
cout <<endl;
}
int main() {
cout << "STL VECTOR TEST START!\n";
//初始化
vector<int> vec_name1;
vector<int> vec_name2(vec_name1);
vector<int> vec_name3(100,1);
vector<int> vec_name4(100);//預設值會是0
//C++标準11,可用數組對vector賦初值初始化
vector<int> vec_name5{1,2,3,4};
int arr[]={0,1,2,3,4};
vector<int> vec_name6(begin(arr),end(arr));
char arr2[]="abcde";
vector<char> vec_name7(begin(arr2),end(arr2));
//使用疊代器周遊,最上面也有封裝周遊列印函數
vector<int>::iterator it;
for( it=vec_name3.begin();it!=vec_name3.end();++it)
{
cout<<*it<<" ";
}
coutall(vec_name7);
//設定空間大小 reserve 和resize 檢視元素個數和空間大小
vec_name3.reserve(200);
vec_name4.resize(200,1);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
cout<<"vec_name4.size ="<<vec_name4.size()<<endl;
cout<<"vec_name4.capacity ="<<vec_name4.capacity()<<endl;
vec_name3.reserve(150);//該語句的修改不會生效,也不會報錯,因為150小于目前capacity200
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
//判斷是否為空
cout<<"vec_name1.empty = "<<vec_name1.empty()<<endl;
cout<<"尾部添加元素 pop_back()"<<endl;
vec_name3.push_back(4);
vec_name3.push_back(5);
coutall(vec_name3);
cout<<"尾部删除元素 pop_back()"<<endl;
vec_name3.pop_back();
coutall(vec_name3);
//任意位置插入元素 insert函數
vec_name3.insert(vec_name3.begin()+1,10); //第一個元素前插入元素,值為10
vec_name3.insert(vec_name3.begin()+1,10); //第一個元素前插入元素,值為10
//删除指定元素
vec_name3.erase(vec_name3.begin()+1); //删除第1個元素
vec_name3.erase(vec_name3.end()-1); //删除最後一個元素
vec_name3.erase(vec_name3.begin()+2,vec_name3.end()-2); //删除區間[i,j];
coutall(vec_name3);
//注意:關于vector的下标操作。vector的下标操作隻能改變或者擷取已有的元素的值,不能往vector裡添加元素!
//使用下标改變元素的值和擷取,但是此方法不會判斷是否越界,是以盡量使用疊代器或者at(),
vec_name3[0] = 20;
for(int i=0;i<vec_name3.size();i++)
{
cout<<vec_name3[i]<<" ";
}
cout<<endl<<vec_name3.at(1)<<endl;
cout<<"傳回第一個元素 front"<<endl;
cout<<vec_name3.front()<<endl;
cout<<"傳回最後一個元素 back"<<endl;
cout<<vec_name3.back()<<endl;
//常用函數,元素排序
sort(vec_name3.begin(),vec_name3.end());
coutall(vec_name3);
//元素查找,find(),求疊代器之間的距離 distance()
vector<int>::iterator result = find(vec_name3.begin(),vec_name3.end(),10);
if(result == vec_name3.end())
{
cout << "沒找到"<<endl;
}
else
{
cout << "存在此元素,元素位數為"<<distance(vec_name3.begin(),result)<<endl;
}
//反轉容器
reverse(vec_name3.begin(),vec_name3.end());
coutall(vec_name3);
//交換元素或交換容器,交換容器是整個容器的元素,可用空間全部交換。
swap(vec_name3[0],vec_name3[1]);
coutall(vec_name3);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
swap(vec_name3,vec_name6);
cout<<"-------after swap-----"<<endl;
coutall(vec_name3);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
//清除容器 clear隻是清除元素,但是空間沒有釋放。
vec_name6.clear();
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
cout<<"第一種方式,定義一個空容器,和之前容器swap,那麼原本有資料有空間的容器就清空了。"<<endl;
vector<int>().swap(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
cout<<"第二種方式,先clear,再使用shrink_to_fit()"<<endl;
coutall(vec_name3);
vec_name3.clear();
vec_name3.shrink_to_fit();
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
cout<<endl<<"STL VECTOR TEST END!\n";
return 0;
}