iterator(迭代器模式)

news/2024/8/26 18:31:02 标签: 迭代器模式, c++

引入

在想显示数组当中所有元素时,我们往往会使用下面的for循环语句来遍历数组

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v({ 1, 2, 3 });
    for (int i = 0; i < v.size(); i++)
    {
        std::cout << v[i] << " " << std::endl;
    }
    return 0;
}

下面我们来对比一下,下面这一段遍历代码

#include <iostream>
#include <map>

int main()
{
    std::map<int, int> mp;
    mp[0] = 1;
    mp[1] = 2;
    mp[2] = 3;
    for(std::map<int, int>::iterator iter = mp.begin(); iter != mp.end(); iter ++)
    {
        std::cout << "key is " << iter->first << " " << "value is " << iter->second << std::endl;
    }
    return 0;
}

二者在功能上实际上是一样的,都是对数据进行遍历输出。
在第一段代码当中,变量i的作用是为了在自增之后,用做访问下一个元素的下标。
在第二段代码当中,变量*iter*也是在自增之后,用来访问mp的下一个元素,我们可以发现, 实际上在第二段代码当中,iterator是对i的一个抽象化、通用化的表达,这就是我们要学习的iterator模式。

iterator模式主要作用是对数据集合按照顺序进行遍历,在遍历的同时还要保证内部信息的封装性,只提供遍历接口。
iterator模式常用于stl容器当中,比如map,list

UML类图

iterator类图

具体代码

book.h

#ifndef __BOOK_H__
#define __BOOK_H__

#include <iostream>
#include <string>

class Book
{
public:
    Book(std::string name)
        :m_nameStr(name)
    {
        std::cout << "value";
    };
    ~Book() = default;
    Book(const Book &other) = default;
    Book& operator=(const Book &other) = default;
    Book& operator=(Book &&other) = delete;

    std::string getName() const
    {
        return m_nameStr;
    };
protected:
    
private:
    std::string m_nameStr;
};

#endif //__BOOK_H__

bookshelf.h

#ifndef __BOOKSHELF_H__
#define __BOOKSHELF_H__

#include <vector>
#include "book.h"

class BookShelf
{
public:
    BookShelf() = default;
    ~BookShelf() = default;
    BookShelf(const BookShelf &other) = default;
    BookShelf& operator=(const BookShelf &other) = default;
    BookShelf(BookShelf &&other) = delete;
    BookShelf& operator=(BookShelf &&other) = delete;

    //实现iterator
    class iterator
    {
    public:
        iterator(Book* tmp = nullptr) :iteratorPtr(tmp) {};
        iterator& operator++()
        {
            iteratorPtr++;
            return *this;
        };
        bool operator==(const iterator& other) const
        {
            return this->iteratorPtr == other.iteratorPtr;
        }
        bool operator!=(const iterator& other) const
        {
            return !(*this == other);
        }
        Book& operator*()
        {
            return *iteratorPtr;
        }
    private:
        Book* iteratorPtr = nullptr;
    };

    //提供遍历起点
    iterator begin();
    
    //提供遍历终点
    iterator end();

    //添加书籍
    void addBook(const Book& tmpBook);
protected:
    
private:
    std::vector<Book> m_bookList;
};

#endif //__BOOKSHELF_H__

bookshelf.cpp

#include "bookshelf.h"

BookShelf::iterator BookShelf::begin()
{
    return iterator(&m_bookList[0]);
}

BookShelf::iterator BookShelf::end()
{
    return iterator(&(m_bookList.back()));
}

void BookShelf::addBook(const Book& tmpBook)
{
    m_bookList.emplace_back(tmpBook);
}

main.cpp

#include "book.h"
#include "bookshelf.h"

int main()
{
    Book book1("第一本书");
    Book book2("第二本书");
    Book book3("第三本书");

    BookShelf woodBookShelf;
    woodBookShelf.addBook(book1);
    woodBookShelf.addBook(book2);
    woodBookShelf.addBook(book3);

    //得不到vector最后一个元素的后一个地址,所以只会输出
    //第一本书、第二本书
    for(BookShelf::iterator iter = woodBookShelf.begin(); iter != woodBookShelf.end(); ++iter)
    {
        std::cout << (*iter).getName() << std::endl;
    }
    system("pause");
    return 0;
}

面向对象

  • 设计模式的作用就是帮助我们编写可复用的类,当一个组件发生改变时,不需要对其他组件进行修改或是只进行很小的修改就可以应付
  • 不要只用具体的类来编程,要优先使用抽象类和接口编程。

参考资料:图解设计模式


http://www.niftyadmin.cn/n/5558341.html

相关文章

STM32-Cube开发资源

全网最完整最干练的CubeMX、CubeIDE STM32开发教程 拥抱高效Cube开发方式【3.1】—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili Kevin_WWW的个人空间-Kevin_WWW个人主页-哔哩哔哩视频 (bilibili.com)

各类专业技术的pdf电子书

从业多年&#xff0c;收集了海量的pdf电子书籍&#xff0c;感兴趣的私聊。

鸿蒙特色物联网实训室

一、 引言 在当今这个万物皆可连网的时代&#xff0c;物联网&#xff08;IoT&#xff09;正以前所未有的速度改变着我们的生活和工作方式。它如同一座桥梁&#xff0c;将实体世界与虚拟空间紧密相连&#xff0c;让数据成为驱动决策和创新的关键力量。随着物联网技术的不断成熟…

【STM32】按键控制LED光敏传感器控制蜂鸣器(江科大)

一、按键控制LED LED.c #include "stm32f10x.h" // Device header/*** 函 数&#xff1a;LED初始化* 参 数&#xff1a;无* 返 回 值&#xff1a;无*/ void LED_Init(void) {/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENAB…

django中日志模块logging的配置和使用

一、文件的配置 settings.py文件中添加LOGGING块的配置&#xff0c;配置如下 # 日志记录 LOGGING {"version": 1,"disable_existing_loggers": False, # 用于确定在应用新的日志配置时是否禁用之前配置的日志器# 格式器"formatters": {"v…

ChatGPT对话:有关花卉数据集

【编者按】编者准备研究基于深度学习的花卉识别&#xff0c;首先需要花卉数据集。 后续&#xff0c;编者不断会记录研究花卉识别过程中的技术知识&#xff0c;敬请围观 1问&#xff1a;推荐一下用于深度学习的花卉数据集 ChatGPT 以下是一些用于深度学习的优秀花卉数据集&am…

图片如何去水印,PS 图片去水印的几种常见方法

在数字图像的世界里&#xff0c;水印常常被用来标识版权或防止未经授权的使用&#xff0c;但有时它们却成为了美观的障碍。无论是出于个人偏好还是专业需求&#xff0c;去除图片上的水印已经成为一项常见的任务。 Adobe Photoshop 作为行业标准的图像编辑软件&#xff0c;提供…

JS之数组中的reduce方法

文章目录 基本语法&#xff1a;callbackFn 的参数:例子1. 数组求和2. 数组求积3. 扁平化数组4. 数组元素计数5. 使用对象解构和展开运算符合并数组中的对象6. 求最大值和最小值 函数组合异步操作中的 reduce总结 reduce 是 JavaScript 中 Array 对象的一个方法&#xff0c;非常…