C++ vector(基礎)
阿新 • • 發佈:2020-12-27
一、什麼是vector?
向量(Vector)是一個封裝了動態大小陣列的順序容器(Sequence Container)。跟任意其它型別容器一樣,它能夠存放各種型別的物件。可以簡單的認為,向量是一個能夠存放任意型別的動態陣列。
二、容器特性
1.順序序列
順序容器中的元素按照嚴格的線性順序排序。可以通過元素在序列中的位置訪問對應的元素。
2.動態陣列
支援對序列中的任意元素進行快速直接訪問,甚至可以通過指標算述進行該操作。操供了在序列末尾相對快速地新增/刪除元素的操作。
3.能夠感知記憶體分配器的(Allocator-aware)
容器使用一個記憶體分配器物件來動態地處理它的儲存需求。
4.函式功能
1.push_back 在陣列的最後新增一個數據
2.pop_back 去掉陣列的最後一個數據
3.at 得到編號位置的資料
4.begin 得到陣列頭的指標
5.end 得到陣列的最後一個單元+1的指標
6.front 得到陣列頭的引用
7.back 得到陣列的最後一個單元的引用
8.max_size 得到vector最大可以是多大
9.capacity 當前vector分配的大小
10.size 當前使用資料的大小
11.resize 改變當前使用資料的大小,如果它比當前使用的大,者填充預設值
12.reserve 改變當前vecotr所分配空間的大小
13. erase 刪除指標指向的資料項
14.clear 清空當前的vector
15.rbegin 將vector反轉後的開始指標返回(其實就是原來的end-1)
16.rend 將vector反轉構的結束指標返回(其實就是原來的begin-1)
17.empty 判斷vector是否為空
18.swap 與另一個vector交換數
**簡單的使用**
使用vector,要新增其標頭檔案#include<vector>。
1.vector的初始化及賦值,比如:
std::vector<int> nVec; // 空物件
std::vector< int> nVec(5,-1); // 建立了一個包含5個元素且值為-1的vector
std::vector<std::string> strVec{"a", "b", "c"}; // 列表初始化
要注意“()”和“{}”這樣的初始化情況,比如:
std::vector<int> nVec(10,1); // 包含10個元素,且值為1
std::vector<int> nVec{10,1}; // 包含2個元素,值分別為10,1
然而,一般在程式中,並不會知道vector的元素個數,故使用以上方式倒顯得繁瑣,所以可以使用push_back,它會負責將一個值當成vector物件的尾元素“壓到(push)”vector物件的“尾端(back)”。比如:
std::vector<int> nVec;
for(int i = 0; i < 5; ++i)
nVec.push_back(i); // 壓入元素
for(size_t i = 0; i < nVec.size(); ++i)
std::cout << nVec[i] << std::endl; // 輸出元素
其中size()是獲取vector元素的個數,另外vector中可使用empty()來返回vector中是否存在元素,如果為空,則返回true,否則返回false。同時,針對nVec[i]是通過下標運算子來獲取對應的vector數值的,千萬注意,針對於空的vector,萬不可通過下標運算子來新增元素,比如:
std::vector<int> nVec;
for(int i = 0; i < 5; ++i)
nVec[i] = i; // error
這樣編寫程式碼是錯誤的,nVec是空的,不包含任何物件。當然也就不可能通過下標來新增或訪問任何元素。若要新增請使用push_back。
當然,針對於輸出,可使用迭代器iterator來表示,比如上面的例子可寫成:
std::vector<int>::iterator itr = nVec.begin();
for(; itr != nVec.end(); ++itr)
std::cout << (*itr) << std::endl;
針對於iterator有兩種標準庫型別: iterator 和 const_iterator。
兩者的區別主要是後者類似於常量指標,只能讀取不能修改。如果vector物件不是常量,兩者均可使用。
2.插入元素
deque像vector一樣提供了隨機訪問元素的能力,但deque支援push_front,且保證在容器首尾進行插入和刪除元素的操作只花常數時間。
使用insert可在容器的任意位置插入0個或多個元素,vector,deque,list和string都支援insert成員。一般insert函式將元素插入到迭代器所指定的位置之前,比如:
slist.insert(iter,"hello"); // 將Hello新增到iter之前的位置
要注意,將元素插入到vector,deque和string中的任何位置都是合法的,但是這樣做會很耗時。
c.insert(pos,num); // 在pos位置插入元素num
c.insert(pos,n,num); // 在pos位置插入n個元素num
c.insert(pos,beg,end); // 在pos位置插入區間為[beg,end)的元素
3.刪除元素
針對於非array容器有多種刪除方式,以erase為例,比如:
c.erase(p); // 刪除迭代器p所指定的元素,返回一個指向被刪除元素之後的迭代器。
c.erase(begin,end); // 刪除b,e所指定範圍內的元素,返回一個指向被刪除元素之後的迭代器。
c.clear(); // 刪除所有元素
注意,刪除元素,會導致迭代器無效。故下面的編寫方式是錯誤的,比如:
std::vector<int> nVec;
for(int i = 0; i < 5; ++i)
nVec.push_back(i);
std::vector<int>::iterator iter = nVec.begin();
for(; iter != nVec.end(); ++iter)
{
if(*iter == 1)
nVec.erase(iter);
}
正確的方式是(刪除特定元素):
std::vector<int>::iterator iter = nVec.begin();
for(; iter != nVec.end();)
{
if(*iter == 0)
iter = nVec.erase(iter);
else
iter++;
}
刪除容器內某一個特定的元素,編寫方式可為:
std::vector<int>::iterator iter = std::find(nVec.begin(),nVec.end(),5);
if(iter != nVec.end())
nVec.erase(iter);
刪除容器內某一段範圍內的元素,編寫方式可為:
first = std::find(nVec.begin(),nVec.end(), value1);
last = std::find(nVec.begin(),nVec.end(), value2);
if(first != nVec.end() && last != nVec.end()) // 判斷有效性
{
nVec.erase(first,last);
}
針對於std::find函式的使用,要包含標頭檔案:#include <algorithm>
刪除容器內所有元素,當然可以這樣:
nVec.erase(nVec.begin(),nVec.end());
不過,偶經常習慣於: nVec.clear();
4. vector的容量與大小:
vector並非隨著每個元素的插入而增長自己,它總是分配一些額外的記憶體容量,這種策略使得vector的效率更高些。若要獲取當前vector的大小,可呼叫size()函式,而獲取當前vector的容量,可呼叫capcity()。
注意,list不需要容量,是由於它的每次增長,只是簡單的連結新元素而已。```
c++ STL中對於verctor 的資料壓入過程應該採用的是深拷貝,同時每壓入一個新的元素時都會將之前的拷貝的物件進行清理,然後壓入新的資料.
測試程式碼:
```c
#include <iostream>
#include <vector>
using namespace std;
class Data
{
public:
Data(int i){
id = i;
return;
};
~Data(){
cout<<"記憶體析構,ID:"<<id<<endl;
return;
}
int id;
};
int main()
{
vector<Data> m_group;
Data pdata(1) ;//= new Data();
Data pdata1(2);// = new Data();
Data pdata2(3);
Data pdata3(4);
m_group.push_back(pdata);
m_group.push_back(pdata1);
m_group.push_back(pdata2);
m_group.push_back(pdata3);
cout<<"Group Size:"<<m_group.size()<<endl;
cout<<"Group capacity():"<<m_group.capacity()<<endl;
/*for each(auto it in m_group)
delete it;*/
m_group.clear();
vector<Data>().swap(m_group);
cout<<"Group Size:"<<m_group.size()<<endl;
cout<<"Group capacity():"<<m_group.capacity()<<endl;
getchar();
return 0;
}
執行結果: