本節(jié)實驗我們將為大家講解迭代器另伍,主要介紹 5 種常見迭代器:輸入鼻百、輸出迭代器,前向逆向迭代器摆尝,雙向迭代器和隨機迭代器愕宋。主要內容包括各自的構造方法和操作方法。
1.1 知識點
輸出迭代器
輸入迭代器
前向迭代器
雙向迭代器
隨機迭代器
迭代器輔助函數
1.2 實驗環(huán)境
g++
ubuntu 16.04
1.3 代碼獲取
可以通過以下鏈接獲取本課程的源碼內容结榄,本次實驗內容主要包含在文件Iterator.h中贝。
//獲取代碼
wget http://labfile.oss.aliyuncs.com/courses/1166/mySTL.zip
unzip -q mySTL.zip -d ./Code/
迭代器(iterator)是一種對象,它能夠用來遍歷標準模板庫容器中的部分或全部元素臼朗,每個迭代器對象代表容器中的確定的地址邻寿。迭代器修改了常規(guī)指針的接口,所謂迭代器是一種概念上的抽象:那些行為上像迭代器的東西都可以叫做迭代器视哑。然而迭代器有很多不同的能力绣否,它可以把抽象容器和通用算法有機的統一起來。迭代器基本分為五種挡毅,輸入輸出迭代器蒜撮,前向逆向迭代器,雙向迭代器和隨機迭代器。
簡單概括:迭代器是一種檢查容器內元素并遍歷元素的可帶泛型數據類型段磨。
下面取逾,我們新建頭文件Iterator.h
是頭文件,用來實現我們的迭代器苹支,這里的代碼需要引用到系統頭文件#include <cstddef>
砾隅,它主要用于定義一些類型。接下來我們定義5種迭代器的類型债蜜,將其寫入Iterator.h
文件中:
struct input_iterator_tag{};//返回輸入迭代器
struct output_iterator_tag{};//返回輸出迭代器
struct forward_iterator_tag :public input_iterator_tag {};//返回前向迭代器
struct bidirectional_iterator_tag :public forward_iterator_tag {};//返回雙向迭代器
struct random_access_iterator_tag :public bidirectional_iterator_tag {};//返回隨機迭代器
輸入迭代器
通過對輸入迭代器解除引用晴埂,它將引用對象,而對象可能位于集合中寻定。通常用于傳遞地址儒洛。
template<class T, class Distance>
struct input_iterator {
typedef input_iterator_tag iterator_category;//返回類型
typedef T value_type;//所指對象類型
typedef Distance difference_type;//迭代器間距離類型
typedef T* pointer;//操作結果類型
typedef T& reference;//解引用操作結果類型
};
輸出迭代器
該類迭代器和輸入迭代器極其相似,也只能單步向前迭代元素狼速,不同的是該類迭代器對元素只有寫的權力晶丘。通常用于返回地址。
struct output_iterator{
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
};
前向迭代器
前向迭代器可以在一個正確的區(qū)間中進行讀寫操作唐含,它擁有輸入迭代器的所有特性浅浮,和輸出迭代器的部分特性,以及單步向前迭代元素的能力捷枯。通常用于遍歷滚秩。
template <class T, class Distance> struct forward_iterator{
typedef forward_iterator_tag iterator_category;
typedefT value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
雙向迭代器
該類迭代器是在前向迭代器的基礎上提供了單步向后迭代元素的能力,前向迭代器的高級版淮捆。
template <class T, class Distance> struct bidirectional_iterator{
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
隨機迭代器
該類迭代器能完成上面所有迭代器的工作郁油,它自己獨有的特性就是可以像指針那樣進行算術計算,而不是僅僅只有單步向前或向后迭代攀痊。
template <class T, class Distance> struct random_access_iterator{
typedef random_access_iterator_tag iterator_category;
typedefT value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
迭代器輔助函數
迭代器的實現桐腌,我們這里主要會使用到兩個函數來輔助完成操作,分別是 advace 函數和 distance 函數苟径。這兩個函數是寫到Algorithm.h文件中的案站。
advance 函數: 用于迭代器前移,增加迭代的位置棘街◇⊙危可用于定向訪問到迭代器的某個變量。
template<class InputIterator, class Distance>
void _advance(InputIterator& it, Distance n, input_iterator_tag){
assert(n >= 0);
while (n--){//當n大于0遭殉,迭代器前移n位
++it;
}
}
void advance(InputIterator& it, Distance n){
typedef typename iterator_traits<InputIterator>::iterator_category iterator_category;
_advance(it, n, iterator_category());
}
distance 函數: 用于計算迭代器間距離
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator first, InputIterator last, input_iterator_tag){
typename iterator_traits<InputIterator>::difference_type dist = 0;//初始化距離
while (first++ != last){//當首地址不等于尾地址石挂,距離增加
++dist;
}
return dist;//返回迭代器間距離
}
template<class Iterator>
typename iterator_traits<Iterator>::difference_type
distance(Iterator first, Iterator last){
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
return _distance(first, last, iterator_category());
}
測試實例
完成上面迭代器的實現后,我們現在在 Test 目錄下新建文件 iteratortest.cpp,用于測試 Iterator 的功能险污。這里的測試我們需要借助到 vector 容器痹愚。關于Vector 容器的內容,我們將在后面的實驗中給大家講解,這里我們直接使用 Vector.h的內容拯腮。該文件可以通過下載課程源碼找到窖式。
#include <iostream>
#include "Iterator.h"
#include "Vector.h"
int main()
{
mySTL::vector<int> vec;
for(int i = 0;i < 10;i++)
vec.push_back(i);
mySTL::vector<int>::iterator it = vec.begin();
mySTL::vector<int>::iterator end = vec.end();
std::cout<<"The value of vector:";
for(;it != vec.end();it++)
std::cout<<*it<<" ";
std::cout<<std::endl;
//advance使用
it = vec.begin();
std::cout<<"After advance 3:";
mySTL::advance(it,3);
std::cout << *it << " "<<std::endl;
//distance使用
std::cout<<"The distance of position 3 to the end:";
std::cout<<mySTL::distance(it,end)<<std::endl;
return 0;
}
command line:
g++ iteratortest.cpp -std=c++11 -o iteratortest -I ../include
./iteratortest
result: