摘要:比起和統(tǒng)一的迭代器和引用更好。因此迭代器失效,實(shí)際就是迭代器底層對(duì)應(yīng)指針?biāo)赶虻目臻g被銷毀了,而使用一塊已經(jīng)被釋放的空間,造成的后果是程序崩潰即如果繼續(xù)使用已經(jīng)失效的迭代器,程序可能會(huì)崩潰。
deques, lists and forward_lists
), vector在訪問元素的時(shí)候更加高效,在末尾添加和刪除元素相對(duì)高效。對(duì)于其它不在末尾的刪除和插入操作,效率更低。比起lists和forward_lists統(tǒng)一的迭代器和引用更好。函數(shù) | 接口說明 |
---|---|
vector() | 無參構(gòu)造 |
vector(size_type n, const value_type& val = value_type()) | 構(gòu)造并初始化n個(gè)val |
vector (const vector& x) | 拷貝構(gòu)造 |
vector (InputIterator first, InputIterator last); | 使用迭代器進(jìn)行初始化構(gòu)造 |
~vector() | 清理動(dòng)態(tài)開辟的空間,無需自己調(diào)用 |
void test1() { vector<int> v1;//無參構(gòu)造 vector<char> v2(3,"a");// 構(gòu)造并初始化3個(gè)a vector<char> v3(v2);//拷貝構(gòu)造v2 int arr[] = {1,2,3,4,5}; vector<int> v4(arr,arr + 5);//使用迭代器進(jìn)行初始化構(gòu)造 for(int i = 0; i < v2.size();i++) cout << v2[i] << endl; for(int i = 0; i < v3.size();i++) cout << v3[i] << endl; for(int i = 0; i < v4.size();i++ ) cout << v4[i] << endl; }
iterator的使用 | 接口說明 |
---|---|
begin() & end() | 獲取第一個(gè)數(shù)據(jù)位置的iterator/const_iterator, 獲取最后一個(gè)數(shù)據(jù)的下一個(gè)位置的iterator/const_iterator |
rbegin() & rend() | 獲取最后一個(gè)數(shù)據(jù)位置的reverse_iterator,獲取第一個(gè)數(shù)據(jù)前一個(gè)位置的reverse_iterator |
void test2(){ vector<int> v(4, 100); //iterator迭代器 vector<int>::iterator it = v.begin(); while(it != v.end()) { *it += 100; cout << *it << " "; it++; } cout << endl; //reverse_iterator反向迭代器 vector<int>::reverse_iterator rit = v.rbegin(); while(rit != v.rend()) { *it -= 100; cout << *rit << " "; rit++; } cout << endl;}
容量空間 | 接口說明 |
---|---|
size() | 獲取數(shù)據(jù)個(gè)數(shù) |
capacity() | 獲取容量大小 |
resize() | 改變vector的size |
reserve() | 改變vector放入capacity |
empty() | 判斷是否為空 |
void test3(){ vector<int> v; cout << v.size() << endl; cout << v.capacity() << endl; v.resize(8); v.reserve(16); cout << v.size() << endl; cout << v.capacity() << endl;}
函數(shù) | 接口說明 |
---|---|
push_back() | 尾插 |
pop_back() | 尾刪 |
insert() | 在pos之前插入val |
erase() | 刪除pos位置的數(shù)據(jù) |
swap | 交換兩個(gè)vector的數(shù)據(jù)空間 |
clear() | 清空當(dāng)前vector的空間 |
operator[] | 像數(shù)組一樣訪問 |
void test4(){ vector<int> v; //尾插5個(gè)元素 v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); //尾刪 v.pop_back(); vector<int>::iterator pos = find(v.begin(),v.end(),3); //在pos前插入3 pos = v.insert(pos, 20); for(int i = 0;i<v.size();i++) { cout << v[i] << " "; } cout << endl; pos = v.erase(pos); vector<int>::iterator it = v.begin(); while(it != v.end()) { cout << *it << " "; it++; } cout << endl; v.clear(); cout << v.size() << endl;}
迭代器的主要作用就是讓算法能夠不用關(guān)心底層數(shù)據(jù)結(jié)構(gòu),其底層實(shí)際就是一個(gè)指針,或者是對(duì)指針進(jìn)行了封裝,比如:vector的迭代器就是原生態(tài)指針T*。因此迭代器失效,實(shí)際就是迭代器底層對(duì)應(yīng)指針?biāo)赶虻目臻g被銷毀了,而使用一塊已經(jīng)被釋放的空間,造成的后果是程序崩潰(即如果繼續(xù)使用已經(jīng)失效的迭代器,程序可能會(huì)崩潰)。
對(duì)于vector可能會(huì)導(dǎo)致其迭代器失效的操作有:
resize、reserve、insert、assign、push_back
等。對(duì)于這類操作導(dǎo)致的迭代器失效,有兩種方面的意義:第一種是發(fā)生了增容,開辟了新的空間,原來的空間釋放了,出現(xiàn)迭代器失效;第二種是迭代器的意義發(fā)生了改變,不再指向原來所指向的元素位置,此時(shí)我們也認(rèn)為迭代器失效了。void test5(){ vector<int> v; //insert導(dǎo)致迭代器失效 v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); cout << v.capacity() << endl;//4 vector<int>::iterator pos = find(v.begin(), v.end(), 2); v.insert(pos, 20); //insert后vector發(fā)生了增容,開辟了新的空間,原來的空間釋放了 //導(dǎo)致此處的pos成了野指針,從而出現(xiàn)迭代器失效 cout << *pos << endl; *pos = 10; for (auto e : v) { cout << e << " "; } cout << endl;}
void test6(){ vector<int> v; //insert導(dǎo)致迭代器失效 v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.reserve(8); vector<int>::iterator pos = find(v.begin(), v.end(), 2); v.insert(pos, 20); //pos的意義發(fā)生了改變,不再指向原來所指向的元素位置 cout << *pos << endl; *pos = 10; for (auto e : v) { cout << e << " "; } cout << endl;}
2. 指定位置元素的刪除操作–erase
erase操作在vector中并不會(huì)出現(xiàn)野指針問題,其迭代器失效常常是指意義上的改變。
void test7(){ vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); vector<int>::iterator pos = find(v.begin(), v.end(), 2); v.erase(pos); *pos = 10;}
對(duì)于這些會(huì)導(dǎo)致迭代器失效的接口,STL都提供了返回值,因此可以讓迭代器接收接口的返回值從而避免迭代器失效的問題。
那么這個(gè)問題要怎么解決呢?我們可以遍歷兩個(gè)容器調(diào)用模板類的賦值深拷貝將vector的每一個(gè)對(duì)應(yīng)元素深拷貝,從而解決這個(gè)問題。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/123199.html
摘要:拷貝構(gòu)造函數(shù)示例構(gòu)造無參構(gòu)造函數(shù)總結(jié)容器和容器的構(gòu)造方式幾乎一致,靈活使用即可賦值操作功能描述給容器進(jìn)行賦值函數(shù)原型重載等號(hào)操作符將區(qū)間中的數(shù)據(jù)拷貝賦值給本身。清空容器的所有數(shù)據(jù)刪除區(qū)間的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。 ...
摘要:走近可以膚淺地理解成為靈活的數(shù)組,我們?cè)诙x數(shù)組的時(shí)候,是要確定數(shù)組的大小的。在內(nèi)部,向量使用一個(gè)動(dòng)態(tài)分配的數(shù)組來存儲(chǔ)它們的元素。當(dāng)插入新元素時(shí),為了增加數(shù)組的大小,可能需要重新分配數(shù)組,這意味著分配一個(gè)新數(shù)組并將所有元素移動(dòng)到該數(shù)組中。 ...
摘要:可以在接口文件中直接引用庫(kù)里的內(nèi)容,大大方便接口文件的編寫。使用庫(kù)里的這里先介紹方式通過創(chuàng)建出來的數(shù)組是數(shù)組的直接代理,非常底層和高效,但是,它也和數(shù)組一樣不安全,一樣沒有邊界檢查。對(duì)由于這種情況,可以使用庫(kù)里的。 如果你也像我們一樣,同時(shí)使用Python和C++,以獲得兩種語(yǔ)言的優(yōu)勢(shì),一定也會(huì)希望尋找一種好的方式集成這兩種語(yǔ)言,相比而言,讓Python能夠方便使用C++的庫(kù)更加重要,...
閱讀 1847·2021-11-22 15:24
閱讀 1307·2021-11-12 10:36
閱讀 3194·2021-09-28 09:36
閱讀 1836·2021-09-02 15:15
閱讀 2744·2019-08-30 15:54
閱讀 2391·2019-08-30 11:02
閱讀 2391·2019-08-29 13:52
閱讀 3539·2019-08-26 11:53