一分钟了解C++迭代器

>>> 背景
最近遇到一个很有趣的问题,大概是信息技术类的中考试题,问题如下。正确答案是a,在python中整数是不可以使用for遍历的,这一点可以立刻通过解释器进行验证。但是如果写成(123, )则会在字面上被认为是一个元组,又是可以通过for遍历的。
python不能对整数使用for循环进行遍历,这是因为整数不是可迭代对象,这里就会涉及一个概念,即迭代器。
>>> 内容
迭代器被引入的动机,就是为了解决不同数据容器的遍历访问方法不同的问题。通过引入迭代器,可以统一化容器的访问,提高代码的复用性,提高程序员的生活质量。
那么我们以python这个迭代问题为引子,来讲一讲c++里面是如何实现迭代器的,并给出一个非常简单的迭代器实例。
我们首先来创建一个数据容器。这个数据容器基本上就是一个数组而已。这里删除了其他的构造方法,仅仅保留一个列表初始化方法,这样我们能通过类似 myarray obj = { 1 , 2 , 3 }; 的方法快速创建一个数据对象。
#include using namespace std;template class myarray final {public: myarray() = delete; myarray(const myarray&) = delete; myarray(const myarray&&) = delete; myarray(const initializer_list &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;};我们在数据类中嵌入了迭代器的定义,这样数据类的引入也会紧跟迭代器的定义,不需要额外引入迭代器定义。可以看到,一个简单的迭代器就是实现了operator*,operator++,operator==和operator!=的类。通过这几个功能,我们就能完成迭代器更迭、迭代器取值的基本功能。
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;
};
// ...
}
这里额外提一下,关于++i和i++的重载。++i返回的是左值,而且是自增之后的值,重载原型使用 iterator& operator ++() 来表示。i++返回的是右值,而且是自增之前的值,所以需要保存一个自增前的对象副本用于返回,重载原型使用 const iterator operator ++(int) ,这里原型使用int纯粹是为了和++i的函数区分(重载只认参数列表而不在乎返回值)。
除此之外,我们的数据类还应该提供迭代器的起始位置和终止位置,也就是常见的begin()和end()方法。
template
class myarray final {
public:
class iterator {
// ...
};
public:
// ...
iterator begin() {
return iterator(_data_ptr);
}
iterator end() {
return iterator(_data_ptr + _size);
}
// ...
};
完成上述工作之后,就可以用迭代器的方法来遍历整个数组啦,甚至可以使用遍历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

爱立信远程竞速赛车颠覆式电竞新体验
LED灯与白炽灯相比有什么优势
浅谈5G、边缘计算及其对政府机构的意义
便携式迷你音箱的续航时间长,适用于多种生活场景
iPhone 12s Pro Max外观渲染图和配置信息曝光
一分钟了解C++迭代器
国内LED行业龙头企业国星光电亮相AWE
科技新潮,4G路由器如何助你畅享网络顺畅
飞利浦电动剃须刀RQ311拆解教程
MAXQ610 16-Bit MAXQ® Micro
价值5万美元的比特币私钥谜题已被破解
光伏系统最长电池寿命的充电控制器设计
即刻预约!相约NEPCON 2023上海电子展共赴电子制造业高端盛会
大陆市场内需助力台电子工业“转型”
为什么说小电容通高频,大电容通低频?
商汤科技闪耀杭州智博会,AI开启无限想象新时代
盘点智能手机屏幕的形态设计
浙江电信的5GC组网部署和实践探讨
浪潮尤为重视新存储在新数据时代的价值 静待2019年的下一轮升级
爆料称苹果iPhone 12系列后置摄像头都将支持夜间模式