一、什么是迭代器?
簡單來說,迭代器就是用來遍歷容器的。
舉個(gè)栗子:對于int型數(shù)組除了用下標(biāo)訪問,還可以通過指針訪問,實(shí)際上迭代器就是對指針進(jìn)行了封裝。
通過代碼了解一下,自己實(shí)現(xiàn)簡單的迭代器:
#include
#include
using namespace std;
void show(int* begin, int* end)//自己寫的輸出函數(shù)
{
while (begin != end)
{
cout << *begin << " ";
begin++;
}
}
int main()
{
int arr[] = { 1,2,3,4,5,68,5,2,14,5,8,4,5,8,2,5,4,5,65,9 };
int len = sizeof(arr) / sizeof(arr[0]);//求出數(shù)組元素個(gè)數(shù)
//指針訪問
int* begin = arr;
int* end = arr + len;
show(begin, end);//在容器中,begin,和end就是迭代器,底層封裝了指針
while (1);
return 0;
}
當(dāng)我們把show函數(shù)編程模板函數(shù)之后,就可以輸出任意類型的數(shù)組了:
template
通過這個(gè)例子我們知道了,可以通過迭代器實(shí)現(xiàn)算法和容器的分離(show函數(shù)可以適配不同類型的數(shù)組)。所以說迭代器是一個(gè)很強(qiáng)的東西~大家好好學(xué)哈
二、迭代器類別
STL 標(biāo)準(zhǔn)庫為每一種標(biāo)準(zhǔn)容器定義了一種迭代器類型,這意味著,不同容器的迭代器也不同,其功能強(qiáng)弱也有所不同。
常用的迭代器按功能強(qiáng)弱分為輸入迭代器、輸出迭代器、前向迭代器、雙向迭代器、隨機(jī)訪問迭代器 5 種
輸入迭代器 :也有叫法稱之為“只讀迭代器”,它從容器中讀取元素,只能一次讀入一個(gè)元素向前移動(dòng),只支持一遍算法,同一個(gè)輸入迭代器不能兩遍遍歷一個(gè)序列。
輸出迭代器 :也有叫法稱之為“只寫迭代器”,它往容器中寫入元素,只能一次寫入一個(gè)元素向前移動(dòng),只支持一遍算法,同一個(gè)輸出迭代器不能兩遍遍歷一個(gè)序列。
正向迭代器 :組合輸入迭代器和輸出迭代器的功能,還可以多次解析一個(gè)迭代器指定的位置,可以對一個(gè)值進(jìn)行多次讀/寫。
雙向迭代器 :組合正向迭代器的功能,還可以通過++操作符向后移動(dòng)位置。
隨機(jī)訪問迭代器 :組合雙向迭代器的功能,還可以向前向后跳過任意個(gè)位置,可以直接訪問容器中任何位置的元素。
迭代器的操作
迭代器 | 操作 |
---|---|
所有迭代器 | it++、++it |
輸入迭代器 | *it、it1=it2、it1==it2、it1!=it2 |
輸出迭代器 | *it、it1=it2 |
正向迭代器 | 提供輸入輸出迭代器的所有功能 |
雙向迭代器 | it--、--it |
隨機(jī)迭代器 | +=、-=、+、-、[]、<、<=、>、>= |
不同容器所支持的迭代器類型表
容器 | 對應(yīng)迭代器類型 |
---|---|
array | 隨機(jī)訪問迭代器 |
vector | 隨機(jī)訪問迭代器 |
deque | 隨機(jī)訪問迭代器 |
list | 雙向迭代器 |
set / multiset | 雙向迭代器 |
map / multimap | 雙向迭代器 |
forward_list | 前向迭代器 |
unordered_map / unordered_multimap | 前向迭代器 |
unordered_set / unordered_multiset | 前向迭代器 |
stack | 不支持迭代器 |
queue | 不支持迭代器 |
三、基本實(shí)現(xiàn)
前面我們說過迭代器實(shí)質(zhì)上就是封裝的指針,那么怎么封裝的呢?
還是看代碼吧~
#include
using namespace std;
class MyIterator
{
public:
MyIterator(int* ptr) :_ptr(ptr) {}
int* operator++()//模仿指針前置++操作
{
_ptr++;
return _ptr;
}
int& operator*()//模仿對指針的取值操作
{
return *_ptr;
}
bool operator!=(MyIterator end)//模仿指針的比較
{
return _ptr != end._ptr;
}
private:
int* _ptr;
};
int main()
{
int arr[] = { 1,2,3,4,5,68,5,2,14,5,8,4,5,8,2,5,4,5,65,9 };
int len = sizeof(arr) / sizeof(arr[0]);
//模擬迭代器訪問
MyIterator begin = arr;
MyIterator end = arr + len;
for (begin; begin != end; ++begin)
{
cout << *begin << " ";
}
while (1);
return 0;
}
把指針封裝到類里面,這樣就可以輕松使用了,不用擔(dān)心出現(xiàn)亂七八糟的問題。
但是,細(xì)心的同學(xué)會發(fā)現(xiàn),操作的時(shí)候是不用指針了,直接操作迭代器就行,但是賦值的時(shí)候還是指針呀~這可咋解決呢?
不要著急,請聽我娓娓道來~我們可以把賦值的指針再封裝一層,直接返回一個(gè)迭代器。不過這里的任務(wù)就比較龐大了,
首先 ,需要把數(shù)組用類封裝(自己實(shí)現(xiàn)簡單的vector);
然后 ,把我們剛剛寫好的迭代器類稍加修改,放到類中(迭代器是一個(gè)類中類);
最后 ,直接把數(shù)組的首地址,和最后一個(gè)元素的下一個(gè)位置分別封裝成返回迭代器的begin()和end()函數(shù)
直接上代碼:
template<typename Data>
class Vector
{
public:
Vector() :_Array(nullptr), _curSize(0), _capacity(0) {}
Vector(int size) :_curSize(0), _capacity(size)
{
_Array = new Data[size];
}
void push_back(Data elem)//插入元素
{
if (_curSize < _capacity)
{
_Array[_curSize] = elem;
_curSize++;
return;
}
}
Data& operator[](int index)//提供下標(biāo)法訪問元素
{
if (index >= 0 && index < _capacity)
{
return _Array[index];
}
cout << "數(shù)組訪問越界" << endl;
}
~Vector()
{
delete[] _Array;
}
public://實(shí)現(xiàn)迭代器
class iterator
{
public:
iterator() :_ptr(nullptr) {}
iterator(Data* ptr) :_ptr(ptr) {}
iterator(const iterator& it)
{
this->_ptr = it._ptr;
}
~iterator() {}
iterator operator=(iterator it)
{
this->_ptr = it._ptr;
return *this;
}
bool operator!=(iterator it)
{
return _ptr != it._ptr;
}
iterator operator++(int)
{
iterator temp = *this;
_ptr++;
return temp;
}
Data& operator*()
{
return *_ptr;
}
Data* operator->()
{
return _ptr;
}
private:
Data* _ptr;
};
//提供用于迭代的begin和end函數(shù),這兩個(gè)函數(shù)一定要放在迭代器類的后面
iterator begin() //返回?cái)?shù)組首地址
{
iterator t(_Array);
return t;
}
iterator end()//返回?cái)?shù)組,最后一個(gè)元素的一下一個(gè)位置的地址
{
iterator t(&_Array[_curSize]);
return t;
}
private:
Data* _Array;//數(shù)組指針
int _curSize;//數(shù)組當(dāng)前元素大小
int _capacity;//數(shù)組最大容量
};
代碼測試:
void Test()
{
Vector<int> vec(10);
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
//能通過迭代器訪問嘛?不能,要自己實(shí)現(xiàn)迭代器之后才能使用
for (Vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
ok,完美~
-
Int
+關(guān)注
關(guān)注
0文章
23瀏覽量
16076 -
數(shù)組
+關(guān)注
關(guān)注
1文章
417瀏覽量
25960 -
迭代器
+關(guān)注
關(guān)注
0文章
43瀏覽量
4316
發(fā)布評論請先 登錄
相關(guān)推薦
評論