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