>>> 背景
最近遇到一個(gè)很有趣的問題,大概是信息技術(shù)類的中考試題,問題如下。正確答案是A,在python中整數(shù)是不可以使用for遍歷的,這一點(diǎn)可以立刻通過解釋器進(jìn)行驗(yàn)證。但是如果寫成(123, )則會(huì)在字面上被認(rèn)為是一個(gè)元組,又是可以通過for遍歷的。
python不能對(duì)整數(shù)使用for循環(huán)進(jìn)行遍歷,這是因?yàn)檎麛?shù)不是可迭代對(duì)象,這里就會(huì)涉及一個(gè)概念,即迭代器。
>>> 內(nèi)容
迭代器被引入的動(dòng)機(jī),就是為了解決不同數(shù)據(jù)容器的遍歷訪問方法不同的問題。通過引入迭代器,可以統(tǒng)一化容器的訪問,提高代碼的復(fù)用性,提高程序員的生活質(zhì)量。
那么我們以python這個(gè)迭代問題為引子,來講一講C++里面是如何實(shí)現(xiàn)迭代器的,并給出一個(gè)非常簡(jiǎn)單的迭代器實(shí)例。
我們首先來創(chuàng)建一個(gè)數(shù)據(jù)容器。這個(gè)數(shù)據(jù)容器基本上就是一個(gè)數(shù)組而已。這里刪除了其他的構(gòu)造方法,僅僅保留一個(gè)列表初始化方法,這樣我們能通過類似 MyArray< int > obj = { 1 , 2 , 3 }; 的方法快速創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象。
#include < iostream >
using namespace std;
template < typename T >
class MyArray final {
public:
MyArray() = delete;
MyArray(const MyArray&) = delete;
MyArray(const MyArray&&) = delete;
MyArray(const initializer_list< T > &v) {
_size = v.size();
_data_ptr = new T[_size];
size_t i = 0;
for (auto it : v) {
*(_data_ptr + i) = it;
++i;
}
}
~MyArray() {delete [] _data_ptr;}
private:
T* _data_ptr;
size_t _size;
};
我們?cè)跀?shù)據(jù)類中嵌入了迭代器的定義,這樣數(shù)據(jù)類的引入也會(huì)緊跟迭代器的定義,不需要額外引入迭代器定義??梢钥吹剑粋€(gè)簡(jiǎn)單的迭代器就是實(shí)現(xiàn)了operator*,operator++,operator==和operator!=的類。通過這幾個(gè)功能,我們就能完成迭代器更迭、迭代器取值的基本功能。
template
class MyArray final {
public:
class Iterator {
public:
Iterator(T* _p) : _curr_ptr(_p) {}
Iterator(const Iterator& other) {
if (this != &other) {
this->_curr_ptr = other._curr_ptr;
}
}
T& operator*() const {
return *_curr_ptr;
}
Iterator& operator++() {
++_curr_ptr;
return *this;
}
const Iterator operator++(int) {
Iterator tmp(*this);
++_curr_ptr;
return tmp;
}
bool operator==(const Iterator& it) const {
return this->_curr_ptr == it._curr_ptr;
}
bool operator!=(const Iterator& it) const {
return !(this == it);
}
private:
T _curr_ptr;
};
// ...
}
這里額外提一下,關(guān)于++i和i++的重載。++i返回的是左值,而且是自增之后的值,重載原型使用 Iterator& operator ++() 來表示。i++返回的是右值,而且是自增之前的值,所以需要保存一個(gè)自增前的對(duì)象副本用于返回,重載原型使用 const Iterator operator ++(int) ,這里原型使用int純粹是為了和++i的函數(shù)區(qū)分(重載只認(rèn)參數(shù)列表而不在乎返回值)。
除此之外,我們的數(shù)據(jù)類還應(yīng)該提供迭代器的起始位置和終止位置,也就是常見的begin()和end()方法。
template
class MyArray final {
public:
class Iterator {
// ...
};
public:
// ...
Iterator begin() {
return Iterator(_data_ptr);
}
Iterator end() {
return Iterator(_data_ptr + _size);
}
// ...
};
完成上述工作之后,就可以用迭代器的方法來遍歷整個(gè)數(shù)組啦,甚至可以使用遍歷for語法。Enjoy!
int main() {
MyArray obj = {1, 2, 3};
for (auto it = obj.begin(); it != obj.end(); ++it) {
cout << *it << " ";
}
cout << endl;
for (auto v : obj) {
cout << v << " ";
}
return 0;
}
1 2 3
1 2 3
-
C++語言
+關(guān)注
關(guān)注
0文章
147瀏覽量
6954 -
python
+關(guān)注
關(guān)注
55文章
4774瀏覽量
84386 -
迭代器
+關(guān)注
關(guān)注
0文章
43瀏覽量
4296
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論