C++-----MySTL实现(4)---迭代器实现

本文介绍了C++中实现MySTL时迭代器的设计,重点讲解了value type、difference type、reference type和pointer type四种迭代器类型,并探讨了迭代器的分类及其在算法效率中的重要性。此外,还展示了迭代器类的定义方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、相关


    iterator.h文件其实并不涉及具体的哪一个容器的迭代器,只是定义了一些统一的标准,比如迭代器相应的型别,比如一个算法需要用到迭代器所指对象的型别,而怎么获得型别在前面traits编程已经说过。根据经验,最常用到的迭代器的型别有五种,value type,difference type,pointer,reference,iterator catagoly。

    value type:是指迭代器所指对象的型别。

    difference type:用来表示两个迭代器之间的距离,因此它也可以用来表示一个容器的最大容量,因为对于一个连续空间的容器而言,头尾之间的距离就是其最大容量。

    reference type:从迭代器所指之物的内容是否允许改变角度来看,迭代器分为两种:不允许改变所指对象的内容,称为constant iterator,例如:const int *pic。允许改变所指对象内容,称为mutable iterator,例如:int*pi。当对一个mutable iterator进行提领时,获得的不应该是一个右值,因为右值不允许赋值。在C++中,函数如果要传回左值,都是以by reference的方式进行的。

    pointer type :pointer和reference在C++中有非常密切的关联,如果传回一个左值,令它代表所指之物是可能的,那么传回一个左值,令它代表所指之物的地址也一定可以,也就是说可以返回一个指针,指向迭代器所指之物。

    iterator catagoly:最后一个迭代器型别会引发大规模的代码工程。在讨论这个型别之前先讨论迭代器的分类: 

// 五种迭代器类型
    //这种迭代器所指的对象不允许外界改变,只读
	struct input_iterator_tag {};  
	//唯写
	struct output_iterator_tag {};
	//允许写入型算法,如replace()在此种迭代器区间上进行读写
	struct forward_iterator_tag : public input_iterator_tag {};
	//可双向移动,某些算法要求
	struct bidirectional_iterator_tag : public forward_iterator_tag {};
	//前四种迭代器只供应一部分指针算术运算,前三种支持operator++,第四种再加上operator--。
	//第五种全都支持,
	struct random_access_iterator_tag : public bidirectional_iterator_tag {};

 

        设计算法时,如果可能尽量针对每种迭代器提供一个明确定义并针对更强化的某种迭代器提供另一种定义,这样才能在不同情况下提供最大效率。

       iterator class不含有任何成员,只是纯粹定义型别,所以继承它不会产生任何负担,后三个参数都有默认值,新迭代器只需要提供前两个参数即可。其定义如下:

//泛化接口,非连续容器实现的迭代器应该继承这个标准迭代器
	template <class _Category, class _T, class _Distance = ptrdiff_t,
		class _Pointer = _T*, class _Reference = _T&>
		struct iterator
	{
		typedef _Category   iterator_category;
		typedef _T          value_type;
		typedef _Distance   difference_type;
		typedef _Pointer    pointer;
		typedef _Reference  reference;
	};

     设计适应的型别是迭代器的责任,设计适当的迭代器是容器的责任,只有容器本身才知道应该设计什么样的迭代器来遍历自己。

2、代码

/*
* 基础迭代器的实现
*/
#ifndef ITERATOR_H_
#define ITERATOR_H_
#include<cstddef> 
namespace MyStl
{
	// 五种迭代器类型
	//这些class只作为标记,所以不需要什么成员
    //这种迭代器所指的对象不允许外界改变,只读
	struct input_iterator_tag {};  
	//唯写
	struct output_iterator_tag {};
	//允许写入型算法,如replace()在此种迭代器区间上进行读写
	struct forward_iterator_tag : public input_iterator_tag {};
	//可双向移动,某些算法要求
	struct bidirectional_iterator_tag : public forward_iterator_tag {};
	//前四种迭代器只供应一部分指针算术运算,前三种支持operator++,第四种再加上operator--。
	//第五种全都支持,
	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;
	};


	template <class _T, class _Distance>
	struct forward_iterator
	{
		typedef forward_iterator_tag iterator_category;
		typedef _T                    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;
		typedef _T                          value_type;
		typedef _Distance                   difference_type;
		typedef _T*                         pointer;
		typedef _T&                         reference;
	};

	//泛化接口,非连续容器实现的迭代器应该继承这个标准迭代器
	template <class _Category, class _T, class _Distance = ptrdiff_t,
		class _Pointer = _T*, class _Reference = _T&>
		struct iterator
	{
		typedef _Category   iterator_category;
		typedef _T          value_type;
		typedef _Distance   difference_type;
		typedef _Pointer    pointer;
		typedef _Reference  reference;
	};
	//iterator型别萃取
	template <class _Iterator>
	struct iterator_traits
	{
		typedef typename _Iterator::iterator_category iterator_category;
		typedef typename _Iterator::value_type        value_type;
		typedef typename _Iterator::difference_type   difference_type;
		typedef typename _Iterator::pointer           pointer;
		typedef typename _Iterator::reference         reference;
	};

	// 针对原生指针而设计的traits偏特化版。
	template <class _T>
	struct iterator_traits<_T*>
	{
		//原生指针的迭代器型别是random_access_iterator_tag
		typedef random_access_iterator_tag  iterator_category;
		typedef _T                          value_type;
		typedef ptrdiff_t                   difference_type;
		typedef _T*                         pointer;
		typedef _T&                         reference;
	};

	// 针对原生top-level const指针设计的traits偏特化版。
	template <class _T>
	struct iterator_traits<const _T*>
	{
		typedef random_access_iterator_tag  iterator_category;
		typedef _T                          value_type; //注意value_type是_T
		typedef ptrdiff_t                   difference_type;
		typedef const _T*                   pointer;
		typedef const _T&                   reference;
	};

	//取得某个迭代器的类型(category)
	template <class _Iterator>
	inline
		typename iterator_traits<_Iterator>::iterator_category iterator_category(const _Iterator&)
	{
		typedef typename iterator_traits<_Iterator>::iterator_category category;
		return category();
	}

	// 取得某个迭代器的distance_type(指针)
	template <class _Iterator>
	inline
		typename iterator_traits<_Iterator>::difference_type* distance_type(const _Iterator&)
	{
		return static_cast<typename iterator_traits<_Iterator>::difference_type*>(0);
	}

	// 取得某个迭代器的value_type(指针)
	template <class _Iterator>
	inline
		typename iterator_traits<_Iterator>::value_type* value_type(const _Iterator&)
	{
		return static_cast<typename iterator_traits<_Iterator>::value_type*>(0);
	}

	// 以下是整组distance函式
	template <class _InputIterator>
	inline
		typename iterator_traits<_InputIterator>::difference_type _distance(_InputIterator first,
			_InputIterator last, input_iterator_tag)
	{
		typename iterator_traits<_InputIterator>::difference_type n = 0;
		while (first != last)
		{
			++first; ++n;
		}
		return n;
	}

	template <class _RandomAccessIterator>
	inline
		typename iterator_traits<_RandomAccessIterator>::difference_type _distance(_RandomAccessIterator first,
			_RandomAccessIterator last, random_access_iterator_tag)
	{
		return last - first;
	}
	//函数distance,用来计算两个迭代器之间的距离,针对不同的迭代器类型
	//跳转到上面其中一个函数
	template <class _InputIterator>
	inline
		typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator first,
			_InputIterator last)
	{
		typedef typename iterator_traits<_InputIterator>::iterator_category category;
		return _distance(first, last, category());
	}



	// 以下是整组 advance 函式
	
	template <class _InputIterator, class _Distance>
	inline void _advance(_InputIterator& i, _Distance n, input_iterator_tag)
	{
		while (n--) ++i;
	}

	template <class BidirectionalIterator, class _Distance>
	inline void _advance(BidirectionalIterator& i, _Distance n,
		bidirectional_iterator_tag)
	{
		if (n >= 0)
			while (n--) ++i;
		else
			while (n++) --i;
	}

	template <class _RandomAccessIterator, class _Distance>
	inline void _advance(_RandomAccessIterator& i, _Distance n,
		random_access_iterator_tag)
	{
		i += n;
	}
	//该函数有两个参数,迭代器p和数值n,函数内部将p累进n次
	//根据迭代器型别跳转到上面其中之一的函数。
	template <class _InputIterator, class _Distance>
	inline void advance(_InputIterator& i, _Distance n)
	{
		_advance(i, n, iterator_category(i));
	}
}//end of MYSTL
#endif //end of ITERATOR_H

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值