设计模式之迭代器模式(C++)

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、迭代器模式是什么?

       迭代器模式是一种行为型的软件设计模式,提供一种方法能顺序访问聚合对象中的各个元素,而又不暴露其内部。

       我们使用的聚合对象各种各样,比如vector、list、tree、map等等,既然是聚合,那就有访问其个体的需要。而遍历访问这个行为可能有深度优先、广度优先、顺序遍历、逆序遍历等等,迭代器的意义就是将这个行为抽离封装起来,这样客户端只需要调用合适的迭代器,来进行对应的遍历,而不用自己去实现这一行为。

       迭代器模式的优点:

  1. 符合单一职责原则。将遍历行为抽离成单独的类。
  2. 符合开闭原则。添加新集合或者新迭代器,不改变原有代码。
  3. 便于扩展多种遍历行为。
  4. 访问数据又不暴露内部。

      迭代器模式的缺点:

  1. 若对聚合对象只需要进行简单的遍历行为,那使用迭代器模式有些大材小用。
  2. 系统复杂性提高,类数量较多。

二、迭代器模式

2.1 结构图

       客户端即Main主函数,容器创建迭代器进行遍历。

2.2 代码示例

       场景描述:设计一个简单容器存放数据,并用迭代器顺序遍历。

//Iterator.h
/****************************************************/
#pragma once
#include <iostream>
#include <unordered_map>
#include <vector>
#include <list>
#include <string>

using namespace std;

// 定义迭代器接口
class Iterator 
{
public:
	// 下一个
	virtual int next() = 0;

	// 是否有下一个
	virtual bool hasNext() = 0;

};

// 定义具体迭代器
class ConcreteIterator : public Iterator 
{
public:
	// 构造函数
	ConcreteIterator(std::vector<int> data) : m_data(data), index(0) {}

	// 下一个
	virtual int next() {
		return m_data[index++];
	}

	// 是否有下一个
	virtual bool hasNext() {
		return index < m_data.size();
	}

private:
	std::vector<int> m_data;
	int index;

};

// 定义容器接口
class Container 
{
public:
	virtual Iterator* create_iterator() = 0;
};

// 定义具体容器
class ConcreteContainer : public Container 
{
public:
	// 构造函数
	ConcreteContainer(std::vector<int> data) : m_data(data) {}

	// 创建迭代器
	virtual Iterator* create_iterator() {
		return new ConcreteIterator(m_data);
	}

private:
	std::vector<int> m_data;

};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Iterator.h"

using namespace std;

int main() 
{
	// 创建容器和迭代器
	std::vector<int> data = { 1, 2, 3, 4, 5 };
	Container* container = new ConcreteContainer(data);
	Iterator* iterator = container->create_iterator();

	// 迭代器输出
	while (iterator->hasNext()) {
		std::cout << iterator->next() << " ";
	}
	
	// 清除
	delete iterator;
	delete container;
	iterator = nullptr;
	container = nullptr;
	return 0;
}

       程序结果如下。

       迭代器应该算是大家熟知的内容了,在使用STL容器时,经常会用到各种迭代器。

三、总结

       我尽可能用较通俗的话语和直观的代码例程,来表述我对迭代器模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解迭代器模式。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
迭代器模式是一种行为型设计模式,它允许客户端通过统一的接口来访问集合中的元素,而不用暴露该集合的底层表示。 在 C++ 中,STL(Standard Template Library)提供了迭代器模式的实现。STL 中定义了五种类型的迭代器:输入迭代器、输出迭代器、正向迭代器、双向迭代器、随机访问迭代器,它们分别对应不同的迭代器行为和性能。 在实现自己的迭代器时,需要定义一个迭代器类,该类应该包含迭代器相关的操作,如:`operator++()`(前缀和后缀版本)、`operator*()`、`operator->()`等。此外,还需要定义迭代器类型别名,如:`value_type`、`iterator_category`、`difference_type`等,它们用于标识迭代器的属性和特征。 以下是一个简单的迭代器类的示例: ```cpp template<typename T> class MyIterator { public: using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; MyIterator(pointer ptr) : m_ptr(ptr) {} reference operator*() const { return *m_ptr; } pointer operator->() const { return m_ptr; } MyIterator& operator++() { ++m_ptr; return *this; } MyIterator operator++(int) { MyIterator temp = *this; ++(*this); return temp; } bool operator==(const MyIterator& other) const { return m_ptr == other.m_ptr; } bool operator!=(const MyIterator& other) const { return !(*this == other); } private: pointer m_ptr; }; ``` 在上述示例中,我们定义了一个指向类型为 `T` 的对象的迭代器类 `MyIterator`,该类包含了迭代器相关的操作和属性。其中,`iterator_category` 属性用于标识迭代器的类型,`value_type` 属性表示迭代器所指对象的类型,`difference_type` 属性表示两个迭代器之间的距离(以整型表示),`pointer` 属性表示迭代器所指对象的指针类型,`reference` 属性表示迭代器所指对象的引用类型。 除了属性之外,我们还定义了构造函数、解引用操作符、箭头操作符、前缀和后缀版本的自增操作符、相等和不等操作符等迭代器操作。 使用自定义的迭代器类时,需要按照 STL 的迭代器接口来使用它,例如: ```cpp #include <iostream> #include <vector> int main() { std::vector<int> v = {1, 2, 3, 4, 5}; MyIterator<int> begin = v.begin(); MyIterator<int> end = v.end(); for (auto it = begin; it != end; ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0; } ``` 在上述示例中,我们使用自定义的迭代器类 `MyIterator` 来遍历一个 vector 容器,并输出容器中的元素。需要注意的是,我们使用了 STL 中的迭代器接口 `begin()` 和 `end()` 来获取容器的起始和结束迭代器,并将它们作为自定义迭代器的构造函数参数。然后,我们使用自定义迭代器来遍历容器,并输出容器中的元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翟天保Steven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值