使用STL的三個境界:能用,明理,,能擴展,。本文屬于第一個境界,如果結(jié)合了《STL源碼解析》,,則達到了第二個境界,如果項目中有需要,對STL進行了擴展則就達到了第三個境界,!如果希望深刻理解vector的這些個成員函數(shù),最好的辦法是詳細了解其內(nèi)部實現(xiàn),,《STL源碼解析》是個好途徑,!當然,也可以直接看編譯器自帶的<vector>的源碼,。
vector是C++標準模板庫中的部分內(nèi)容,,vector之所以被認為是一個容器,是因為它能夠像容器一樣存放各種類型的對象,,簡單地說,,vector是一個能夠存放任意類型的動態(tài)數(shù)組。 為了使用vector,,必須包含頭文件<vector>,。另,vector屬于std命名空間,,因此需要通過命名限定,,可以有如下三種方式,后兩種方式更好,,因為未引入的無關(guān)的內(nèi)容,。(依稀記的《Effective C++》的某個條款這個提過!) using namespace std; using namespace std::vector; std::vector<int> vec;
現(xiàn)在以 std::vector<int> vec為例,,描述相關(guān)函數(shù)的功能,!
第一部分:
vec.begin()//指向迭代器中第一個元素。 vec.end()//指向迭代器中末端元素的下一個,,指向一個不存在元素,。 vec.push_back(elem) //在尾部加入一個數(shù)據(jù)。 vec.pop_back() //刪除最后一個數(shù)據(jù),。 vec.capacity() //vector可用空間的大小,。 vec.size()//返回容器中數(shù)據(jù)個數(shù)。 vec.front() //傳回第一個數(shù)據(jù),。 vec.back() //傳回最后一個數(shù)據(jù),不檢查這個數(shù)據(jù)是否存在,。 vec.at(index) //傳回索引idx所指的數(shù)據(jù),,如果idx越界,,拋出out_of_range。 vec.clear() //移除容器中所有數(shù)據(jù),。 vec.erase(iterator) //刪除pos位置的數(shù)據(jù),,傳回下一個數(shù)據(jù)的位置。 vec.erase(begin,end) //刪除[beg,end)區(qū)間的數(shù)據(jù),,傳回下一個數(shù)據(jù)的位置,。注意:begin和end為iterator vec.insert(position,elem) //在pos位置插入一個elem拷貝,傳回新數(shù)據(jù)位置,。 vec.insert(position,n,elem) //在pos位置插入n個elem數(shù)據(jù),,無返回值。 vec.insert(position,begin,end) //在pos位置插入在[beg,end)區(qū)間的數(shù)據(jù),,無返回值,。
以下代碼驗證上述這些常用函數(shù)的功能:
vector<int>::iterator iter; vector<int>::iterator begin=vec.begin(); vector<int>::iterator end=vec.end(); for(iter=begin; iter!=end; iter++) cout<<"size:"<<vec.size()<<endl; cout<<"capacity:"<<vec.capacity()<<endl;
cout<<"push back 1 and 2 based on above;vec:"; for(iter=begin; iter!=end; iter++) cout<<"size:"<<vec.size()<<endl; cout<<"capacity:"<<vec.capacity()<<endl;
cout<<"pop one element based on above;vec:"; for(iter=begin; iter!=end; iter++) cout<<"size:"<<vec.size()<<endl; cout<<"capacity:"<<vec.capacity()<<endl; cout<<"vec is empty"<<endl; cout<<"vec is not empty"<<endl; cout<<"based on the above:"<<endl; cout<<" vec.front():"<<vec.front()<<endl; cout<<" vec.back():"<<vec.back()<<endl; cout<<" size:"<<vec.size()<<endl; cout<<" capacity:"<<vec.capacity()<<endl; for(iter=begin; iter!=end; iter++)
cout<<"call at(),based on the above:"<<endl; cout<<" vec.at():"<<vec.at(3)<<endl; cout<<" size:"<<vec.size()<<endl; cout<<" capacity:"<<vec.capacity()<<endl; for(iter=begin; iter!=end; iter++) cout<<"call clear(),based on the above:"<<endl; cout<<" size:"<<vec.size()<<endl; cout<<" capacity:"<<vec.capacity()<<endl; for(iter=begin; iter!=end; iter++) cout<<"push_back 1,2,3,4,5,6,7 based on above;vec:"; for(iter=begin; iter!=end; iter++)
vec.erase(vec.begin()+2); cout<<"call vec.erase(3),vec:"; for(iter=begin; iter!=end; iter++) cout<<" size:"<<vec.size()<<endl; cout<<" capacity:"<<vec.capacity()<<endl; vec.erase(vec.begin()+1,vec.begin()+3); cout<<"call vec.erase(1,3),vec:"; for(iter=begin; iter!=end; iter++) cout<<" size:"<<vec.size()<<endl; cout<<" capacity:"<<vec.capacity()<<endl; return 1;<span style="font-family: Arial, Helvetica, sans-serif;">}</span>
輸出結(jié)果如下:
vector中v[i]與v.at(i)的區(qū)別:參見:http://www.cnblogs.com/zhuyf87/archive/2012/12/06/2805579.html
如果v非空,A行和B行沒有任何區(qū)別,。如果v為空,,B行會拋出std::out_of_range異常,A行的行為未定義,。 c++標準不要求vector<T>::operator[]進行下標越界檢查,,原因是為了效率,總是強制下標越界檢查會增加程序的性能開銷,。設計vector是用來代替內(nèi)置數(shù)組的,所以效率問題也應該考慮,。不過使用operator[]就要自己承擔越界風險了,。如果需要下標越界檢查,請使用at,。
第二部分:
void assign(const_iterator first,const_iterator last); //功能:將區(qū)間[first,last)的元素賦值到當前的vector中,,當前vector會清除掉容器中之前的內(nèi)容。 void assign(size_type n,const T& x = T()); //功能:賦n個值為x的元素到當前vector中,,當前vector會清除掉容器中之前的內(nèi)容,。
以下函數(shù)驗證assign函數(shù)的功能:
vector<int>::iterator iter; for(int i=10; i<60; i+=10)
for (iter = v1.begin(); iter != v1.end(); iter++)
for (iter = v2.begin(); iter != v2.end(); iter++)
v1.assign(v2.begin(), v2.end()); for (iter = v2.begin(); iter != v2.end(); iter++) for (iter = v3.begin(); iter != v3.end(); iter++)
運行結(jié)果如下:
第三部分:
vec.rbegin()//傳回一個vector的最后一個數(shù)據(jù)的指針。 vec.rend()// 傳回一個vector的第一個數(shù)據(jù)前一個位置的指針,。,?
驗證代碼如下:
vector<int>::iterator iter; for(int i=10; i<60; i+=10)
for (iter = v1.begin(); iter != v1.end(); iter++)
for (iter = v2.begin(); iter != v2.end(); iter++) vector<int>::reverse_iterator r_iter; cout << "v1 in reverse "; for (r_iter = v1.rbegin(); r_iter != v1.rend(); r_iter++) cout<<"v1.rbegin():"<<*v1.rbegin()<<endl; cout<<"v1.rbegin():"<<(*(v1.rbegin()--))<<endl; cout<<"v1.rend()--:"<<*(v1.rend()--)<<endl;
cout<<"v1.rend()++:"<<*(v1.rend()++)<<endl;
輸出結(jié)果為:
此處有個疑問:對(*(v1.rbegin()++))、(*(v1.begin()++)),、(*(v1.rbegin()--)),、(*(v1.begin()--))均沒達到預期,需要看下其內(nèi)部究竟是怎么實現(xiàn)的,!
另外,,注意:企圖直接打印迭代器,,編譯是通不過的!eg:cout<< v1.begin();
第四部分:
vec.resize(num)//重新指定vector的長度,。 vec.resize(num,value)//重新指定vector的長度,。并設定新增的元素的值
當需要以vec[size+1]=vec[j];的方式對超過vector的size賦值時,都需要先調(diào)用下resize()函數(shù),,如果直接對超出vector.size()的位置賦值,,編譯不能通過!
如上所示,,一種是僅僅設定size,,另一種即設定size也設定value;其實resize函數(shù)就是重新設定finish指針。如果在調(diào)用resize函數(shù)時,,發(fā)現(xiàn)vector沒有剩余的空間了,,則會以當前的size為基礎,申請開辟2倍的空間,。(開辟空間,,拷貝,釋放原有空間的過程)
第五部分:
vector<int>::iterator iter; vector<int>::iterator begin=vec.begin(); vector<int>::iterator end=vec.end(); for(iter=begin; iter!=end; iter++) cout<<"size:"<<vec.size()<<endl; cout<<"capacity:"<<vec.capacity()<<endl; vector<int>(vec).swap(vec); cout<<"vector<int>(vec)-swap-capacity:"<<vec.capacity()<<endl; cout<<"vector<int>(vec)-swap-size:"<<vec.size()<<endl;
cout<<"temp-swap-capacity:"<<vec.capacity()<<endl; cout<<"temp-swap-size:"<<vec.size()<<endl;
cout<<"vector<int>()-swap-capacity:"<<vec.capacity()<<endl; cout<<"vector<int>()-swap-size:"<<vec.size()<<endl;
輸出結(jié)果為:
vector<int>::iterator iter; vector<int>::iterator begin=vec.begin(); vector<int>::iterator end=vec.end(); for(iter=begin; iter!=end; iter++) cout<<"vec size:"<<vec.size()<<endl; cout<<"vec capacity:"<<vec.capacity()<<endl;
cout<<"vec1 size:"<<vec1.size()<<endl; cout<<"vec1 capacity:"<<vec1.capacity()<<endl;
for(iter=begin; iter!=end; iter++) cout<<"vec size after swap():"<<vec.size()<<endl; cout<<"vec capacity after swap():"<<vec.capacity()<<endl;
cout<<"after swap vec1:"; for(iter=begin; iter!=end; iter++) cout<<"vec1 size after swap():"<<vec1.size()<<endl; cout<<"vec1 capacity after swap():"<<vec1.capacity()<<endl;
輸出結(jié)果為:
該結(jié)果表明<algorithm>中的函數(shù)swap(),,只是交換兩個vector中的內(nèi)容,,其原本的size和capacity均不做改變!
vec.reserve()//設定capacity的值,,如果小于原本的capacity的值則保持為原本的capacity的值,。
以下為顯而易見的操作: operator[]://此函數(shù)返回的是容器中指定位置的一個引用。 operattor*://指針的取址操作
若干種創(chuàng)建方式(vector的構(gòu)造函數(shù)) vector<type> vec vector<type> vec(vec1) vector<type> vec=vec1 vector<type> vec(n) vector<type> vec(n,elem) vector<type> vec(begin,end) vector<type> vec{a,b,c,……} vector<type> vec={a,b,c,……}
|