C++ STL標(biāo)準(zhǔn)庫(kù)std::vector的使用詳解
1. 簡(jiǎn)介
vector 是表示可以改變大小的數(shù)組的序列容器。
與arrays一樣,vector 對(duì)元素使用連續(xù)的存儲(chǔ)位置,這意味著也可以使用指向其元素的常規(guī)指針上的偏移量來(lái)訪(fǎng)問(wèn)它們的元素,并且與在數(shù)組中一樣高效。但是與arrays不同,它們的大小可以動(dòng)態(tài)變化,容器會(huì)自動(dòng)處理它們的存儲(chǔ)。
在內(nèi)部,vector 使用一個(gè)動(dòng)態(tài)分配的數(shù)組來(lái)存儲(chǔ)它們的元素。這個(gè)數(shù)組可能需要重新分配,以便在插入新元素時(shí)增大大小,這意味著分配一個(gè)新數(shù)組并將所有元素移動(dòng)到其中。就處理時(shí)間而言,這是一項(xiàng)相對(duì)昂貴的任務(wù),因此,vector 不會(huì)在每次向容器添加元素時(shí)重新分配。
相反,vector 容器可以分配一些額外的存儲(chǔ)空間以適應(yīng)可能的增長(zhǎng),因此容器的實(shí)際容量可能大于嚴(yán)格需要的存儲(chǔ)容量(即容器的大小)。庫(kù)可以實(shí)現(xiàn)不同的增長(zhǎng)策略,以平衡內(nèi)存使用和重新分配,但在任何情況下,重新分配只應(yīng)在大小的對(duì)數(shù)增長(zhǎng)間隔進(jìn)行,以便在向量末尾插入單個(gè)元素可以提供攤余的恒定時(shí)間復(fù)雜度(請(qǐng)參閱“推后”)。
因此,與arrays相比,vector 消耗更多的內(nèi)存,以換取管理存儲(chǔ)和以高效方式動(dòng)態(tài)增長(zhǎng)的能力。
與其他動(dòng)態(tài)序列容器(deques、list和forward_list)相比,vectors可以非常高效地訪(fǎng)問(wèn)其元素(就像數(shù)組一樣),并相對(duì)高效地從其末尾添加或刪除元素。對(duì)于涉及在結(jié)尾以外的位置插入或刪除元素的操作,它們的性能比其他操作差,迭代器和引用的一致性也不如列表和轉(zhuǎn)發(fā)列表。
2. 使用示例
#include <iostream> #include <string> #include <vector> using namespace std; void main() { vector<string>myvt; // 定義模板類(lèi)對(duì)象 myvt.reserve(4); // 設(shè)置大小 cout << "The size is 4." << endl; // 添加內(nèi)容 myvt.push_back("1. Beijing City."); myvt.push_back("2. Tianjin City."); myvt.push_back("3. Shanghai City."); myvt.push_back("4. Chongqing City."); // 打印內(nèi)容 vector<string>::iterator it; for(it=myvt.begin();it!=myvt.end();it++) { cout<<*it<<endl; } int m=myvt.size(); // 獲取大小 int n=myvt.capacity(); // 獲取容量 int m1=myvt.max_size(); // 獲取最大大小 cout<<"vector:myvt, size is "<<m<<endl; cout<<"vector:myvt, capacity is "<<n<<endl; cout<<"vector:myvt, maxsize is "<<m1<<endl; myvt.resize(10); //重設(shè)大小 cout<<"resize: 10."<<endl; int n1=myvt.capacity(); int n2=myvt.size(); cout<<"vector:myvt, capacity is "<<n1<<endl; cout<<"vector:myvt, size is "<<n2<<endl; // 如果為空值則打印 * 號(hào) for(it=myvt.begin();it!=myvt.end();it++) { if(*it=="") cout<<"******"<<endl; cout<<*it<<endl; } cin.get(); }
3. 構(gòu)造、析構(gòu)、賦值
3.1 std::vector::vector 構(gòu)造函數(shù)
(1) 空容器構(gòu)造函數(shù)
(默認(rèn)構(gòu)造函數(shù))構(gòu)造一個(gè)沒(méi)有元素的空容器。
(2) 填充構(gòu)造函數(shù)
用n個(gè)元素構(gòu)造一個(gè)容器。每個(gè)元素都是val的副本(如果提供)。
(3) 范圍構(gòu)造函數(shù)
構(gòu)造一個(gè)包含與range[first,last]一樣多的元素的容器,每個(gè)元素的emplace都是按照相同的順序從該范圍中的相應(yīng)元素構(gòu)造的。
(4) 復(fù)制構(gòu)造函數(shù)(并使用分配器復(fù)制)
以相同的順序構(gòu)造一個(gè)容器,其中包含x中每個(gè)元素的副本。
(5) 移動(dòng)構(gòu)造函數(shù)(并使用分配器移動(dòng))
構(gòu)造一個(gè)獲取x元素的容器。
如果alloc被指定并且與x的分配器不同,那么元素將被移動(dòng)。否則,就不會(huì)構(gòu)建任何元素(它們的所有權(quán)被直接轉(zhuǎn)移)。
x處于未指定但有效的狀態(tài)。
(6) 初始化列表構(gòu)造
以相同的順序構(gòu)造一個(gè)容器,其中包含il中每個(gè)元素的副本。
#include <iostream> #include <string> #include <vector> using namespace std; void main() { vector<string>myvt; // 定義模板類(lèi)對(duì)象 myvt.reserve(4); // 設(shè)置大小 cout << "The size is 4." << endl; // 添加內(nèi)容 myvt.push_back("1. Beijing City."); myvt.push_back("2. Tianjin City."); myvt.push_back("3. Shanghai City."); myvt.push_back("4. Chongqing City."); // 打印內(nèi)容 vector<string>::iterator it; for(it=myvt.begin();it!=myvt.end();it++) { cout<<*it<<endl; } int m=myvt.size(); // 獲取大小 int n=myvt.capacity(); // 獲取容量 int m1=myvt.max_size(); // 獲取最大大小 cout<<"vector:myvt, size is "<<m<<endl; cout<<"vector:myvt, capacity is "<<n<<endl; cout<<"vector:myvt, maxsize is "<<m1<<endl; myvt.resize(10); //重設(shè)大小 cout<<"resize: 10."<<endl; int n1=myvt.capacity(); int n2=myvt.size(); cout<<"vector:myvt, capacity is "<<n1<<endl; cout<<"vector:myvt, size is "<<n2<<endl; // 如果為空值則打印 * 號(hào) for(it=myvt.begin();it!=myvt.end();it++) { if(*it=="") cout<<"******"<<endl; cout<<*it<<endl; } cin.get(); }
3.2 std::vector::~vector 析構(gòu)函數(shù)
~vector();
Destroys the container object.
3.3 std::vector::operator= “=”符號(hào)
// vector assignment #include <iostream> #include <vector> int main () { std::vector<int> foo (3,0); // foo: 0 0 0 std::vector<int> bar (5,0); // bar: 0 0 0 0 0 bar = foo; // bar: 0 0 0 foo = std::vector<int>(); // foo: std::cout << "Size of foo: " << int(foo.size()) << '\n'; std::cout << "Size of bar: " << int(bar.size()) << '\n'; return 0; }
4. Iterators 迭代器
4.1 std::vector::begin
返回指向容器中第一個(gè)元素的迭代器。
返回指向向量中第一個(gè)元素的迭代器。
注意,與member vector::front不同,member vector::front返回對(duì)第一個(gè)元素的引用,該函數(shù)返回指向該元素的隨機(jī)訪(fǎng)問(wèn)迭代器。
如果容器為空,則返回的迭代器值不應(yīng)被取消引用。
4.2 std::vector::end
返回指向容器最后一個(gè)元素所在位置后一個(gè)位置的迭代器,通常和 begin() 結(jié)合使用。
返回一個(gè)迭代器,該迭代器引用向量容器中過(guò)去的結(jié)束元素。
過(guò)去的結(jié)束元素是理論元素,它將跟隨向量中的最后一個(gè)元素。它不指向任何元素,因此不應(yīng)被取消引用。
由于標(biāo)準(zhǔn)庫(kù)的函數(shù)使用的范圍不包括其結(jié)束迭代器所指向的元素,因此此函數(shù)通常與vector::begin結(jié)合使用,以指定一個(gè)包含容器中所有元素的范圍。
如果容器為空,此函數(shù)將返回與vector::begin相同的值。
// vector::begin/end #include <iostream> #include <vector> int main () { std::vector<int> myvector; for (int i=1; i<=5; i++) myvector.push_back(i); std::cout << "myvector contains:"; for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; }
4.3 std::vector::rbegin
返回指向最后一個(gè)元素的迭代器。
返回指向向量中最后一個(gè)元素的反向迭代器(即它的反向開(kāi)始)。
反向迭代器向后迭代:增加它們會(huì)將它們移向容器的開(kāi)頭。
rbegin指向成員端將指向的元素之前的元素。
注意,與member vector::back不同,member vector::back返回對(duì)同一元素的引用,此函數(shù)返回反向隨機(jī)訪(fǎng)問(wèn)迭代器。
4.4 std::vector::rend
返回指向第一個(gè)元素所在位置前一個(gè)位置的迭代器。
返回一個(gè)反向迭代器,該迭代器指向向量中第一個(gè)元素之前的理論元素(該元素被視為其反向末端)。
vector::rbegin和vector::rend之間的范圍包含向量的所有元素(按相反的順序)。
// vector::rbegin/rend #include <iostream> #include <vector> int main() { std::vector<int> myvector(5); // 5個(gè)默認(rèn)構(gòu)造整數(shù) int i = 0; std::vector<int>::reverse_iterator rit = myvector.rbegin(); for (; rit != myvector.rend(); ++rit) *rit = ++i; std::cout << "myvector contains:"; for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; }
4.5 std::vector::cbegin (C++11)
和 begin() 功能相同,只不過(guò)在其基礎(chǔ)上,增加了 const 屬性,不能用于修改元素。
const_iterator cbegin() const noexcept;
返回指向容器中第一個(gè)元素的常量迭代器。
const_iterator是指向const內(nèi)容的迭代器。這個(gè)迭代器可以增加和減少(除非它本身也是const),就像vector::begin返回的迭代器一樣,但是它不能用來(lái)修改它指向的內(nèi)容,即使vector對(duì)象本身不是const。
如果容器為空,則返回的迭代器值不應(yīng)被取消引用。
4.6 std::vector::cend(C++11)
和 end() 功能相同,只不過(guò)在其基礎(chǔ)上,增加了 const 屬性,不能用于修改元素。
const_iterator cend() const noexcept;
返回一個(gè)指向容器中結(jié)束元素的常量迭代器。
const_iterator是指向const內(nèi)容的迭代器。這個(gè)迭代器可以增加和減少(除非它本身也是const),就像vector::end返回的迭代器一樣,但是它不能用來(lái)修改它指向的內(nèi)容,即使vector對(duì)象本身不是const。
如果容器為空,此函數(shù)將返回與vector::cbegin相同的值。
返回的值不應(yīng)被取消引用。
// vector::cbegin/cend #include <iostream> #include <vector> int main () { std::vector<int> myvector = {10,20,30,40,50}; std::cout << "myvector contains:"; for (auto it = myvector.cbegin(); it != myvector.cend(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; }
4.7 std::vector::crbegin (C++11)
和 rbegin() 功能相同,只不過(guò)在其基礎(chǔ)上,增加了 const 屬性,不能用于修改元素。
const_reverse_iterator crbegin() const noexcept;
返回一個(gè)const_reverse_迭代器,指向容器中的最后一個(gè)元素(即它的反向開(kāi)始)。
4.8 std::vector::crend(C++11)
和 rend() 功能相同,只不過(guò)在其基礎(chǔ)上,增加了 const 屬性,不能用于修改元素。
const_reverse_iterator crend() const noexcept;
返回一個(gè)const_reverse_迭代器,該迭代器指向容器中第一個(gè)元素之前的理論元素(該元素被視為其反向端)。
// vector::crbegin/crend #include <iostream> #include <vector> int main () { std::vector<int> myvector = {1,2,3,4,5}; std::cout << "myvector backwards:"; for (auto rit = myvector.crbegin(); rit != myvector.crend(); ++rit) std::cout << ' ' << *rit; std::cout << '\n'; return 0; }
5. Capacity 容量
5.1 std::vector::size 查詢(xún)大小
返回實(shí)際元素個(gè)數(shù)。
size_type size() const noexcept;
返回矢量中的元素?cái)?shù)。
這是向量中保存的實(shí)際對(duì)象的數(shù)量,它不一定等于它的存儲(chǔ)容量。
// vector::size #include <iostream> #include <vector> int main () { std::vector<int> myints; std::cout << "0. size: " << myints.size() << '\n'; for (int i=0; i<10; i++) myints.push_back(i); std::cout << "1. size: " << myints.size() << '\n'; myints.insert (myints.end(),10,100); std::cout << "2. size: " << myints.size() << '\n'; myints.pop_back(); std::cout << "3. size: " << myints.size() << '\n'; return 0; }
5.2 std::vector::max_size
返回元素個(gè)數(shù)的最大值。這通常是一個(gè)很大的值,一般是 232-1,所以我們很少會(huì)用到這個(gè)函數(shù)。
size_type max_size() const noexcept;
返回向量可以容納的最大元素?cái)?shù)。
這是由于已知的系統(tǒng)或庫(kù)實(shí)現(xiàn)限制,容器可以達(dá)到的最大潛在大小,但容器決不能保證能夠達(dá)到該大小:在達(dá)到該大小之前,它仍然可能無(wú)法在任何時(shí)候分配存儲(chǔ)。
// comparing size, capacity and max_size #include <iostream> #include <vector> int main() { std::vector<int> myvector; // 向myvector中添加內(nèi)容 for (int i = 0; i < 100; i++) myvector.push_back(i); std::cout << "size: " << myvector.size() << "\n"; std::cout << "capacity: " << myvector.capacity() << "\n"; std::cout << "max_size: " << myvector.max_size() << "\n"; return 0; }
5.3 std::vector::resize
改變實(shí)際元素的個(gè)數(shù)。
void resize (size_type n); void resize (size_type n, const value_type& val);
調(diào)整容器大小,使其包含n個(gè)元素。
如果n小于當(dāng)前容器的大小,則內(nèi)容將縮減為其前n個(gè)元素,移除超出的元素(并銷(xiāo)毀它們)。
如果n大于當(dāng)前容器大小,則通過(guò)在末尾插入足夠多的元素來(lái)擴(kuò)展內(nèi)容,以達(dá)到n的大小。如果指定了val,則將新元素初始化為val的副本,否則,它們將被值初始化。
如果n也大于當(dāng)前容器容量,則自動(dòng)重新分配已分配的存儲(chǔ)空間。
請(qǐng)注意,此函數(shù)通過(guò)插入或刪除容器中的元素來(lái)更改容器的實(shí)際內(nèi)容。
// resizing vector #include <iostream> #include <vector> int main() { std::vector<int> myvector; // 初始化內(nèi)容 for (int i = 1; i < 10; i++) myvector.push_back(i); myvector.resize(5); myvector.resize(8, 100); myvector.resize(12); std::cout << "myvector contains:"; for (int i = 0; i < myvector.size(); i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
5.4 std::vector::capacity
返回當(dāng)前容量。
size_type capacity() const noexcept;
返回當(dāng)前為向量分配的存儲(chǔ)空間的大小,以元素表示。
這個(gè)容量不一定等于向量大小。它可以相等或更大,額外的空間可以適應(yīng)增長(zhǎng),而不需要在每次插入時(shí)重新分配。
請(qǐng)注意,此容量不假定對(duì)向量大小有限制。當(dāng)這個(gè)容量耗盡并且需要更多容量時(shí),容器會(huì)自動(dòng)擴(kuò)展它(重新分配它的存儲(chǔ)空間)。向量大小的理論限制由成員max_size給出。
可以通過(guò)調(diào)用成員vector::reserve顯式更改向量的容量。
// comparing size, capacity and max_size #include <iostream> #include <vector> int main () { std::vector<int> myvector; // set some content in the vector: for (int i=0; i<100; i++) myvector.push_back(i); std::cout << "size: " << (int) myvector.size() << '\n'; std::cout << "capacity: " << (int) myvector.capacity() << '\n'; std::cout << "max_size: " << (int) myvector.max_size() << '\n'; return 0; }
5.5 std::vector::empty
** 判斷容器中是否有元素,若無(wú)元素,則返回 true;反之,返回 false。**
bool empty() const noexcept;
返回向量是否為空(即其大小是否為0)。
此函數(shù)不會(huì)以任何方式修改容器。若要清除向量的內(nèi)容,請(qǐng)參見(jiàn)vector::clear。
// vector::empty #include <iostream> #include <vector> int main () { std::vector<int> myvector; int sum (0); for (int i=1;i<=10;i++) myvector.push_back(i); while (!myvector.empty()) { sum += myvector.back(); myvector.pop_back(); } std::cout << "total: " << sum << '\n'; return 0; }
5.6 std::vector::reserve
增加容器的容量。
void reserve (size_type n);
要求向量容量至少足以包含n個(gè)元素。
如果n大于當(dāng)前向量容量,函數(shù)將使容器重新分配其存儲(chǔ)空間,將其容量增加到n(或更大)。
在所有其他情況下,函數(shù)調(diào)用不會(huì)導(dǎo)致重新分配,向量容量也不會(huì)受到影響。
此函數(shù)對(duì)向量大小沒(méi)有影響,并且不能更改其元素。
// vector::reserve #include <iostream> #include <vector> int main() { std::vector<int>::size_type sz; std::vector<int> foo; sz = foo.capacity(); std::cout << "making foo grow:\n"; for (int i = 0; i < 100; ++i) { foo.push_back(i); if (sz != foo.capacity()) { sz = foo.capacity(); std::cout << "容量已更改: " << sz << '\n'; } } std::vector<int> bar; sz = bar.capacity(); bar.reserve(100); // 這是與上面的foo唯一的區(qū)別 std::cout << "making bar grow:\n"; for (int i = 0; i < 100; ++i) { bar.push_back(i); if (sz != bar.capacity()) { sz = bar.capacity(); std::cout << "容量已更改: " << sz << '\n'; } } return 0; }
5.7 std::vector::shrink_to_fit (C++11)
將內(nèi)存減少到等于當(dāng)前元素實(shí)際所使用的大小。
void shrink_to_fit();
請(qǐng)求容器減小其容量以適合其大小。
請(qǐng)求是非綁定的,容器實(shí)現(xiàn)可以自由地進(jìn)行優(yōu)化,使向量的容量大于其大小。
這可能會(huì)導(dǎo)致重新分配,但對(duì)向量大小沒(méi)有影響,并且無(wú)法更改其元素。
// vector::shrink_to_fit #include <iostream> #include <vector> int main() { std::vector<int> myvector(100); std::cout << "1. myvector的容量: " << myvector.capacity() << '\n'; myvector.resize(10); std::cout << "2. myvector的容量: " << myvector.capacity() << '\n'; myvector.shrink_to_fit(); std::cout << "3. myvector的容量: " << myvector.capacity() << '\n'; return 0; }
6. Element access 元素訪(fǎng)問(wèn)
6.1 std::vector::operator[]
重載了 [ ] 運(yùn)算符,可以向訪(fǎng)問(wèn)數(shù)組中元素那樣,通過(guò)下標(biāo)即可訪(fǎng)問(wèn)甚至修改 vector 容器中的元素。
reference operator[] (size_type n); const_reference operator[] (size_type n) const;
返回對(duì)向量容器中位置n處元素的引用。
類(lèi)似的成員函數(shù)vector :: at與該運(yùn)算符具有相同的行為,不同之處在于vector :: at已進(jìn)行邊界檢查,并通過(guò)引發(fā)out_of_range異常來(lái)發(fā)出信號(hào),以指示請(qǐng)求的位置是否超出范圍。
可移植程序永遠(yuǎn)不要使用參數(shù)n超出范圍來(lái)調(diào)用此函數(shù),因?yàn)檫@會(huì)導(dǎo)致未定義的行為。
// vector::operator[] #include <iostream> #include <vector> int main() { std::vector<int> myvector(10); // 10個(gè)零初始化元素 std::vector<int>::size_type sz = myvector.size(); // 分配一些值: for (unsigned i = 0; i < sz; i++) myvector[i] = i; // reverse vector using operator[]: for (unsigned i = 0; i < sz / 2; i++) { int temp; temp = myvector[sz - 1 - i]; myvector[sz - 1 - i] = myvector[i]; myvector[i] = temp; } std::cout << "myvector contains:"; for (unsigned i = 0; i < sz; i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
6.2 std::vector::at
使用經(jīng)過(guò)邊界檢查的索引訪(fǎng)問(wèn)元素。
reference at (size_type n); const_reference at (size_type n) const;
返回對(duì)向量中位置n處元素的引用。
該函數(shù)自動(dòng)檢查n是否在向量中的有效元素的范圍內(nèi),如果不是,則拋出out_of_range異常(即,如果n大于或等于其大小)。 這與成員operator []不同,后者不檢查邊界。
// vector::at #include <iostream> #include <vector> int main() { std::vector<int> myvector(10); // 10個(gè)零初始化的整數(shù) // 分配一些值: for (unsigned i = 0; i < myvector.size(); i++) myvector.at(i) = i; std::cout << "myvector contains:"; for (unsigned i = 0; i < myvector.size(); i++) std::cout << ' ' << myvector.at(i); std::cout << '\n'; return 0; }
6.3 std::vector::front
返回第一個(gè)元素的引用。
reference front(); const_reference front() const;
返回對(duì)向量中第一個(gè)元素的引用。
與成員vector :: begin返回一個(gè)迭代器到同一元素不同,此函數(shù)返回直接引用。
在空容器上調(diào)用此函數(shù)會(huì)導(dǎo)致未定義的行為。
// vector::front #include <iostream> #include <vector> int main() { std::vector<int> myvector; myvector.push_back(78); myvector.push_back(16); // 現(xiàn)在前排等于78,后排等于16 myvector.front() -= myvector.back(); std::cout << "myvector.front() is now " << myvector.front() << '\n'; return 0; }
6.4 std::vector::back
返回最后一個(gè)元素的引用。
reference back(); const_reference back() const;
返回對(duì)向量中最后一個(gè)元素的引用。
與成員向量::: end返回僅在此元素之后的迭代器不同,該函數(shù)返回直接引用。
在空容器上調(diào)用此函數(shù)會(huì)導(dǎo)致未定義的行為。
// vector::back #include <iostream> #include <vector> int main () { std::vector<int> myvector; myvector.push_back(10); while (myvector.back() != 0) { myvector.push_back ( myvector.back() -1 ); } std::cout << "myvector contains:"; for (unsigned i=0; i<myvector.size() ; i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
6.5 std::vector::data (C++11)
返回指向容器中第一個(gè)元素的指針。
value_type* data() noexcept; const value_type* data() const noexcept;
返回指向向量?jī)?nèi)部用于存儲(chǔ)其擁有的元素的內(nèi)存數(shù)組的直接指針。
由于保證向量中的元素以與向量表示相同的順序存儲(chǔ)在連續(xù)的存儲(chǔ)位置中,因此檢索到的指針可以偏移以訪(fǎng)問(wèn)數(shù)組中的任何元素。
// vector::data #include <iostream> #include <vector> int main () { std::vector<int> myvector (5); int* p = myvector.data(); *p = 10; ++p; *p = 20; p[2] = 100; std::cout << "myvector contains:"; for (unsigned i=0; i<myvector.size(); ++i) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
7. Modifiers 內(nèi)容修改
7.1 std::vector::assign
用新元素替換原有內(nèi)容。
range (1) template <class InputIterator> void assign (InputIterator first, InputIterator last); fill (2) void assign (size_type n, const value_type& val); initializer list (3) void assign (initializer_list<value_type> il);
將新內(nèi)容分配給向量,替換其當(dāng)前內(nèi)容,并相應(yīng)地修改其大小。
在范圍版本(1)中,新內(nèi)容是從第一個(gè)到最后一個(gè)范圍內(nèi)的每個(gè)元素以相同順序構(gòu)造的元素。
在填充版本(2)中,新內(nèi)容是n個(gè)元素,每個(gè)元素都初始化為val的副本。
在初始化程序列表版本(3)中,新內(nèi)容是作為初始化程序列表傳遞的值的副本,順序相同。
如果發(fā)生重新分配,則使用內(nèi)部分配器(通過(guò)其特征)分配和取消分配存儲(chǔ)。 它還可用于銷(xiāo)毀所有現(xiàn)有元素,并構(gòu)造新元素。
// vector assign #include <iostream> #include <vector> int main() { std::vector<int> first; std::vector<int> second; std::vector<int> third; first.assign(7, 100); // 7個(gè)整數(shù),值為100 std::vector<int>::iterator it; it = first.begin() + 1; second.assign(it, first.end() - 1); // 從第2個(gè)值到到數(shù)第1個(gè)值 int myints[] = { 1776,7,4 }; third.assign(myints, myints + 3); // 從數(shù)組分配 std::cout << "Size of first: " << int(first.size()) << '\n'; std::cout << "Size of second: " << int(second.size()) << '\n'; std::cout << "Size of third: " << int(third.size()) << '\n'; return 0; }
7.2 std::vector::push_back
在序列的尾部添加一個(gè)元素。
void push_back (const value_type& val); void push_back (value_type&& val);
在向量的末尾,當(dāng)前向量的最后一個(gè)元素之后,添加一個(gè)新元素。 val的內(nèi)容被復(fù)制(或移動(dòng))到新元素。
這有效地將容器大小增加了一個(gè),這會(huì)導(dǎo)致分配的存儲(chǔ)空間自動(dòng)重新分配,前提是(且僅當(dāng))新向量大小超過(guò)當(dāng)前向量容量時(shí)。
// vector::push_back #include <iostream> #include <vector> int main() { std::vector<int> myvector; int myint; std::cout << "請(qǐng)輸入一些整數(shù) (輸入0結(jié)束):\n"; do { std::cin >> myint; myvector.push_back(myint); } while (myint); std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n"; return 0; }
7.3 std::vector::pop_back
移出序列尾部的元素。
void pop_back();
刪除向量中的最后一個(gè)元素,從而有效地將容器大小減小了一個(gè)。
這會(huì)破壞已刪除的元素。
// vector::pop_back #include <iostream> #include <vector> int main() { std::vector<int> myvector; int sum(0); myvector.push_back(100); myvector.push_back(200); myvector.push_back(300); while (!myvector.empty()) { sum += myvector.back(); myvector.pop_back(); } std::cout << "myvector的元素總計(jì)為: " << sum << '\n'; return 0; }
7.4 std::vector::insert
在指定的位置插入一個(gè)或多個(gè)元素。
single element (1) iterator insert (const_iterator position, const value_type& val); fill (2) iterator insert (const_iterator position, size_type n, const value_type& val); range (3) template <class InputIterator> iterator insert (const_iterator position, InputIterator first, InputIterator last); move (4) iterator insert (const_iterator position, value_type&& val); initializer list (5) iterator insert (const_iterator position, initializer_list<value_type> il);
通過(guò)在元素前面的指定位置插入新元素來(lái)擴(kuò)展向量,有效地通過(guò)插入元素的數(shù)量增加容器的大小。
這將導(dǎo)致當(dāng)且僅當(dāng)新矢量大小超過(guò)當(dāng)前矢量容量時(shí)自動(dòng)重新分配分配的存儲(chǔ)空間。
因?yàn)橄蛄渴褂脭?shù)組作為其底層存儲(chǔ),所以在向量結(jié)尾以外的位置插入元素會(huì)導(dǎo)致容器將位置之后的所有元素重新定位到新位置。與其他類(lèi)型的序列容器(如list或forward_list)對(duì)同一操作執(zhí)行的操作相比,這通常是一種低效的操作。
參數(shù)決定插入多少個(gè)元素以及它們被初始化到哪些值:
// inserting into a vector #include <iostream> #include <vector> int main() { std::vector<int> myvector(3, 100); std::vector<int>::iterator it; it = myvector.begin(); it = myvector.insert(it, 200); myvector.insert(it, 2, 300); // "it" 不再有效,請(qǐng)換一個(gè)新的: it = myvector.begin(); std::vector<int> anothervector(2, 400); myvector.insert(it + 2, anothervector.begin(), anothervector.end()); int myarray[] = { 501,502,503 }; myvector.insert(myvector.begin(), myarray, myarray + 3); std::cout << "myvector contains:"; for (it = myvector.begin(); it < myvector.end(); it++) std::cout << ' ' << *it; std::cout << '\n'; return 0; }
7.5 std::vector::erase
移出一個(gè)元素或一段元素。
iterator erase (const_iterator position); iterator erase (const_iterator first, const_iterator last);
從向量中移除單個(gè)元素(位置)或一系列元素([第一個(gè),最后一個(gè))。
這有效地減少了容器的大小,減少了被銷(xiāo)毀的元素的數(shù)量。
因?yàn)橄蛄渴褂靡粋€(gè)數(shù)組作為其底層存儲(chǔ),所以在向量末尾以外的位置刪除元素會(huì)導(dǎo)致容器在刪除段后將所有元素重新定位到新位置。與其他類(lèi)型的序列容器(如list或forward_list)對(duì)同一操作執(zhí)行的操作相比,這通常是一種低效的操作。
// erasing from vector #include <iostream> #include <vector> int main() { std::vector<int> myvector; // set some values (from 1 to 10) for (int i = 1; i <= 10; i++) myvector.push_back(i); // erase the 6th element myvector.erase(myvector.begin() + 5); // erase the first 3 elements: myvector.erase(myvector.begin(), myvector.begin() + 3); std::cout << "myvector contains:"; for (unsigned i = 0; i < myvector.size(); ++i) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
7.6 std::vector::swap
交換兩個(gè)容器的所有元素。
void swap (vector& x);
通過(guò)x的內(nèi)容交換容器的內(nèi)容,x是另一個(gè)相同類(lèi)型的向量對(duì)象。尺寸可能不同。
調(diào)用此成員函數(shù)后,此容器中的元素是調(diào)用之前在x中的元素,x的元素是此調(diào)用之前在x中的元素。所有迭代器、引用和指針對(duì)于交換的對(duì)象仍然有效。
請(qǐng)注意,存在一個(gè)同名的非成員函數(shù)swap,并使用類(lèi)似于此成員函數(shù)的優(yōu)化重載該算法。
// swap vectors #include <iostream> #include <vector> int main() { std::vector<int> foo(3, 100); // 100 100 100 std::vector<int> bar(5, 200); // 200 200 200 200 200 foo.swap(bar); std::cout << "foo contains:"; for (unsigned i = 0; i < foo.size(); i++) std::cout << ' ' << foo[i]; std::cout << '\n'; std::cout << "bar contains:"; for (unsigned i = 0; i < bar.size(); i++) std::cout << ' ' << bar[i]; std::cout << '\n'; return 0; }
7.7 std::vector::clear
移出所有的元素,容器大小變?yōu)?0。
void clear() noexcept;
從向量中移除所有元素(已銷(xiāo)毀),使容器的大小為0。
不能保證會(huì)發(fā)生重新分配,也不能保證由于調(diào)用此函數(shù)而改變向量容量。強(qiáng)制重新分配的典型替代方法是使用swap:
// clearing vectors #include <iostream> #include <vector> int main () { std::vector<int> myvector; myvector.push_back (100); myvector.push_back (200); myvector.push_back (300); std::cout << "myvector contains:"; for (unsigned i=0; i<myvector.size(); i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; myvector.clear(); myvector.push_back (1101); myvector.push_back (2202); std::cout << "myvector contains:"; for (unsigned i=0; i<myvector.size(); i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; return 0; }
7.8 std::vector::emplace(C++11)
在指定的位置直接生成一個(gè)元素。
emplace() 每次只能插入一個(gè)元素,而不是多個(gè)。 emplace() 在插入元素時(shí),是在容器的指定位置直接構(gòu)造元素,而不是先單獨(dú)生成,再將其復(fù)制(或移動(dòng))到容器中。因此,在實(shí)際使用中,推薦大家優(yōu)先使用 emplace()。
template <class... Args> iterator emplace (const_iterator position, Args&&... args);
通過(guò)在位置插入新元素來(lái)擴(kuò)展容器。 這個(gè)新元素是使用args作為其構(gòu)造參數(shù)構(gòu)建的。
這有效地將容器尺寸增加了一個(gè)。
當(dāng)且僅當(dāng)新向量大小超過(guò)當(dāng)前向量容量時(shí),才會(huì)自動(dòng)重新分配已分配的存儲(chǔ)空間。
由于向量使用數(shù)組作為其基礎(chǔ)存儲(chǔ),因此在向量末端以外的位置插入元素會(huì)導(dǎo)致容器將位置后的所有元素都移動(dòng)一個(gè)到其新位置。 與其他類(lèi)型的序列容器(例如list或forward_list)執(zhí)行的操作相比,這通常是一種低效的操作。 請(qǐng)參閱emplace_back以獲取直接在末尾擴(kuò)展容器的成員函數(shù)。
通過(guò)轉(zhuǎn)發(fā)帶有args的allocator_traits :: construct來(lái)就地構(gòu)建元素。
存在一個(gè)類(lèi)似的成員函數(shù),插入,該成員函數(shù)將現(xiàn)有對(duì)象復(fù)制或移動(dòng)到容器中。
// vector::emplace #include <iostream> #include <vector> int main () { std::vector<int> myvector = {10,20,30}; auto it = myvector.emplace ( myvector.begin()+1, 100 ); myvector.emplace ( it, 200 ); myvector.emplace ( myvector.end(), 300 ); std::cout << "myvector contains:"; for (auto& x: myvector) std::cout << ' ' << x; std::cout << '\n'; return 0; }
7.9 std::vector::emplace_back (C++11)
在序列尾部生成一個(gè)元素。
emplace_back() 的執(zhí)行效率比 push_back() 高。因此,在實(shí)際使用時(shí),建議大家優(yōu)先選用 emplace_back()。
template <class... Args> void emplace_back (Args&&... args);
在最后構(gòu)造并插入元素在向量的最后一個(gè)元素之后,在向量的末尾插入一個(gè)新元素。 使用args作為其構(gòu)造函數(shù)的參數(shù)在適當(dāng)?shù)奈恢脴?gòu)造此新元素。
這有效地將容器大小增加了一個(gè),這會(huì)導(dǎo)致分配的存儲(chǔ)空間自動(dòng)重新分配,前提是(且僅當(dāng))新向量大小超過(guò)當(dāng)前向量容量時(shí)。
通過(guò)轉(zhuǎn)發(fā)帶有args的allocator_traits :: construct來(lái)就地構(gòu)建元素。
存在類(lèi)似的成員函數(shù)push_back,該函數(shù)將現(xiàn)有對(duì)象復(fù)制或移動(dòng)到容器中。
// vector::emplace_back #include <iostream> #include <vector> int main () { std::vector<int> myvector = {10,20,30}; myvector.emplace_back (100); myvector.emplace_back (200); std::cout << "myvector contains:"; for (auto& x: myvector) std::cout << ' ' << x; std::cout << '\n'; return 0; }
到此這篇關(guān)于C++ STL標(biāo)準(zhǔn)庫(kù)std::vector的使用詳解的文章就介紹到這了,更多相關(guān)C++ STL std::vector內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)簡(jiǎn)易通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)易通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06Qt連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查的圖文教程
QT連接數(shù)據(jù)庫(kù)是應(yīng)用開(kāi)發(fā)的常用基礎(chǔ)操作,經(jīng)過(guò)實(shí)驗(yàn)我總結(jié)了一些例程,下面這篇文章主要給大家介紹了關(guān)于Qt連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04使用C語(yǔ)言實(shí)現(xiàn)本地socke通訊的方法
這篇文章主要介紹了?使用C語(yǔ)言實(shí)現(xiàn)本地socke通訊,代碼分為服務(wù)器代碼和客戶(hù)端代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12C++ auto自動(dòng)類(lèi)型推導(dǎo)規(guī)則和使用詳解
C++11 賦予 auto 關(guān)鍵字新的含義,使用它來(lái)做自動(dòng)類(lèi)型推導(dǎo)。也就是說(shuō),使用了 auto 關(guān)鍵字以后,編譯器會(huì)在編譯期間自動(dòng)推導(dǎo)出變量的類(lèi)型,這樣我們就不用手動(dòng)指明變量的數(shù)據(jù)類(lèi)型了2022-08-08C++基于socket編程實(shí)現(xiàn)聊天室功能
這篇文章主要介紹了C++基于socket編程實(shí)現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07七夕表白! C語(yǔ)言實(shí)現(xiàn)愛(ài)情紅玫瑰
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)愛(ài)情紅玫瑰,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法
這篇文章主要介紹了C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下2014-10-10