首先,我们先看看使用 foreach 的时候,都发生了什么。
新建一个类,根据经验,我们 for 一个对象应该是这样的:
1 |
for (XX::iterator iter = xx.begin(); iter != xx.end(); ++iter) |
所以,迭代器, beigin(), end() 应该是会用得到的,我们做个试验:
Generator.h
1 2 3 4 5 6 7 |
class Generator { public: typedef int* iterator; iterator begin(); iterator end(); }; |
Generator.cpp
1 2 3 4 5 6 7 8 9 10 11 |
Generator::iterator Generator::begin() { std::cout<< "begin()" <<std::endl; return nullptr; } Generator::iterator Generator::end() { std::cout<< "end()" <<std::endl; return nullptr; } |
main.cpp
1 2 3 4 5 |
Generator g; for (auto i : g) { std::cout<< i <<std::endl; } |
运行结果:
1 2 |
begin() end() |
说明我们想的没错,foreach 跟上边的 for 的行为是一样的。
插个体外话,(发现字打错了,不过不改了,还是挺哏儿的)
1. 之前以为 for (const auto i : g) 会调用 const 版本的 cbegin cend ,然而 并不会。
2. iterator 叫什么名字都没什么所谓,起名叫 红太阳 也ok。
接下来,处理一下迭代器:(我想确认一下丫具体被如何操 做)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
class iterator { public: iterator(int* p) : _p(p) { } int* operator()() { std::cout<< "operator()" <<std::endl; return _p; } int operator*() { std::cout<< "openator*" <<std::endl; return 0; } iterator& operator++() { std::cout<< "++operator" <<std::endl; ++_p; return *this; } iterator operator++(int) { std::cout<< "operator++" <<std::endl; return _p++; } bool operator==(const iterator& it) { std::cout<< "operator==" <<std::endl; return true; } bool operator!= (const iterator& it) { std::cout<< "operator!=" <<std::endl; return true; } private: int* _p; }; |
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
begin() end() operator!= openator* 0 ++operator operator!= openator* 0 ++operator operator!= openator* 0 |
已经足够说明问题了,自己把剩下的细节补充上就好了。
总结一下要点:
1. begin() end()
2. 迭代器
3. 迭代器重载 !=
4. 迭代器重载 前++
5. 迭代器重载 *(解引用)