容器迭代器iterator

文章目录

      • 1、自定义String实现iterator
      • 2、自定义vector实现iterator
      • 3、迭代器失效问题

迭代器的功能:提供一种统一的方式,来透明的遍历容器。

迭代器可以透明的访问容器内部的元素的值,而无需了解其底层遍历机制具体是数组的下标还是链表的指针等等。

泛型算法参数接收的都是迭代器!
泛型算法 - 全局的函数 - 给所有容器用的
泛型算法,有一套方式,能够统一的遍历所有的容器的元素 - 迭代器

1、自定义String实现iterator

#include <iostream>
#pragma warning(disable:4996)using namespace std;class String {
public:String(const char *p = nullptr) {if (p != nullptr) {_pstr = new char[strlen(p) + 1];strcpy(_pstr, p);}else {_pstr = new char[1];_pstr[0] = '\0';}}~String() {delete[] _pstr;_pstr = nullptr;}String(const String &str) {_pstr = new char[strlen(str._pstr) + 1];strcpy(_pstr, str._pstr);}String &operator=(const String &str) {if (this == &str) return *this;delete[] _pstr;_pstr = new char[strlen(str._pstr) + 1];strcpy(_pstr, str._pstr);return *this;}bool operator>(const String &str) const {return strcmp(_pstr, str._pstr) > 0;}bool operator<(const String &str) const {return strcmp(_pstr, str._pstr) < 0;}bool operator==(const String &str) const {return strcmp(_pstr, str._pstr) == 0;}int length() const { return strlen(_pstr); }const char *c_str() const { return _pstr; }//char ch=str6[6]; str6[6]='7'char &operator[](int index) { return _pstr[index]; }//char ch=str6[6]; 不允许修改! str6[6]='7'const char &operator[](int index) const { return _pstr[index]; }// 给string字符串类型提供迭代器的实现class iterator {public:iterator(char *p = nullptr) : _p(p){}bool operator!=(const iterator &it) {return _p != it._p;}void operator++() {++_p;}char &operator*() {return *_p;}private:char *_p;};// begin返回的是容器底层首元素的迭代器的表示iterator begin() { return iterator(_pstr); }// end返回的是容器末尾元素后继位置的迭代器的表示iterator end() { return iterator(_pstr + length()); }private:char *_pstr;friend String operator+(const String &lhs, const String &rhs);friend ostream &operator<<(ostream &out, const String &str);
};String operator+(const String &lhs, const String &rhs) {//char *ptmp = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1];//strcpy(ptmp, lhs._pstr);//strcat(ptmp, rhs._pstr);//return String(ptmp); // 内存泄漏:ptmp 未释放//char *ptmp = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1];//strcpy(ptmp, lhs._pstr);//strcat(ptmp, rhs._pstr);//String tmp(ptmp); // 效率太低//delete[] ptmp; //return tmp;String result;delete[] result._pstr; // 释放默认构造的空字符串内存result._pstr = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1];strcpy(result._pstr, lhs._pstr);strcat(result._pstr, rhs._pstr);return result;
}ostream &operator<<(ostream &out, const String &str) {out << str._pstr;return out;
}int main() {String str1 = "hello world!";// 容器的迭代器类型String::iterator it = str1.begin();for (; it != str1.end(); ++it) {cout << *it << " ";}cout << endl;// C++11 foreach的方式来遍历容器的内部元素的值 => 底层,还是通过迭代器进行for (auto s : str1) {cout << s << " ";}cout << endl;return 0;
}

2、自定义vector实现iterator

#include <iostream>
using namespace std;template<typename T>
class vector {
public:vector(int size = 10) {_first = new T[size];_last = _first;_end = _first + size;}~vector() {delete[]_first;_first = _last = _end = nullptr;}vector(const vector<T> &rhs) {int size = rhs._end - rhs - _first;_first = new T[size];int len = rhs._last - rhs._first;for (int i = 0; i < len; ++i) {_first[i] = rhs._first[i];}_last = _first + len;_end = _first + size;}vector<T> &operator=(const vector<T> &rhs) {if (this == &rhs) {return *this;}delete[]_first;int size = rhs._end - rhs - _first;_first = new T[size];int len = rhs._last - rhs._first;for (int i = 0; i < len; ++i) {_first[i] = rhs._first[i];}_last = _first + len;_end = _first + size;return *this;}void push_back(const T &val) {if (full()) {expand();}*_last++ = val;}void pop_back() {if (empty()) {return;}--_last;}T back() {// 返回容器末尾元素的值return *(_last - 1);}bool full() const { return _last == _end; }bool empty() const { return _last == _first; }int size() const { return _end - _first; }T &operator[](int index) { // vec[2]if (index < 0 || index >= size()) {throw "OutOfRangeException";}return _first[index];}//迭代器一般实现成容器的嵌套类型class iterator {public:iterator(T *ptr = nullptr) : _ptr(ptr){}bool operator!=(const iterator &it) const {return _ptr != it._ptr;}void operator++() {_ptr++;}T &operator*() {return *_ptr;}private:T *_ptr;};// 需要给容器提供begin和end方法iterator begin() { return iterator(_first); }iterator end() { return iterator(_last); }private:T *_first; // 指向数组空间的起始位置T *_last;// 指向数组中有效元素的后继位置T *_end;// 指向数组空间的后继位置void expand() {int size = _end - _first;T *ptmp = new T[size * 2];for (int i = 0; i < size; ++i) {ptmp[i] = _first[i];}delete[] _first;_first = ptmp;_last = _first + size;_end = _last + size;}
};class Test {
public:Test() { cout << "Test()" << endl; }~Test() { cout << "~Test()" << endl; }
};int main() {vector<int> vec;for (int i = 0; i < 20; ++i) {vec.push_back(rand() % 100);}for (int i = 0; i < vec.size();  ++i) {cout << vec[i] << " ";}cout << endl;//vector<int>::iterator it = vec.begin();auto it = vec.begin();for (; it != vec.end(); ++it) {cout << *it << " ";}cout << endl;for (auto v : vec) {cout << v << " ";}cout << endl;return 0;
}

3、迭代器失效问题

问题引入

	vector<int> vec;for (int i = 0; i < 20; ++i) {vec.push_back(rand() % 100);}// 把vec容器中所有的偶数全部删除auto it = vec.begin();for (; it != vec.end(); ++it) {if (*it % 2 == 0) {//迭代器失效的问题,第一次调用erase以后,迭代器it就失效了vec.erase(it);  // insert(it,val) erase(it)break;}}//给vec容器中所有的偶数前面添加一个小于偶数值1的数字auto it= vec.begin();for (; it != vec.end(); ++it) {if (*it % 2 == 0) {// 这里的迭代器在第一次insert之后,iterator就失效了vec.insert(it, *it - 1);break;}}	

迭代器为什么会失效?

a. 当容器调用erase方法后,当前位置到容器末尾元素的所有的迭代器全部失效了。

b. 当容器调用insert方法后,当前位置到容器末尾元素的所有的迭代器全部失效了。
    首元素-> 插入点/删除点:迭代器依然有效
    插入点/删除点->末尾元素:迭代器全部失效

c. insert来说,如果引起容器内存扩容。
    首元素-> 插入点/删除点 ->末尾元素:原来容器的所有的迭代器就全部失效了

迭代器失效了以后,问题该怎么解决?

对插入/删除点的迭代器进行更新操作。

	vector<int> vec;for (int i = 0; i < 20; ++i) {vec.push_back(rand() % 100);}for (auto v : vec) {cout << v << " ";}cout << endl;// 把vec容器中所有的偶数全部删除auto it = vec.begin();while (it != vec.end()) {if (*it % 2 == 0) {//迭代器失效的问题,第一次调用erase以后,迭代器it就失效了it = vec.erase(it);  // insert(it,val) erase(it)}else {++it;}}for (auto v : vec) {cout << v << " ";}cout << endl;//给vec容器中所有的偶数前面添加一个小于偶数值1的数字auto it = vec.begin();for (; it != vec.end(); ++it) {if (*it % 2 == 0) {// 这里的迭代器在第-次insert之后,iterator就失效了it = vec.insert(it, *it - 1);//break;++it;}}	for (auto v : vec) {cout << v << " ";}cout << endl;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/894561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对象的实例化、内存布局与访问定位

一、创建对象的方式 二、创建对象的步骤: 一、判断对象对应的类是否加载、链接、初始化: 虚拟机遇到一条new指令&#xff0c;首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已经被加载、解析和初始化…

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…

实验十一 Servlet(二)

实验十一 Servlet(二) 【实验目的】 1&#xff0e;了解Servlet运行原理 2&#xff0e;掌握Servlet实现方式 【实验内容】 改造实验10&#xff0c;引入数据库&#xff0c;创建用户表&#xff0c;包括用户名和密码&#xff1a;客户端通过login.jsp发出登录请求&#xff0c;请求…

服务SDK三方新版中央仓库和私服发布详解

预备信息Github仓库发布Gradle版本匹配Gradle项目构建全局变量定义Gradle项目Nexus仓库配置与发布过程Gradle项目发布至Sonatype中央仓库配置过程总结当我们在实现一个项目技术总结、工具类封装或SDK封装,通常是为了方便开发者使用特定服务或平台而提供的一组工具和API。您可能…

openmv的端口被拆分为两个 导致电脑无法访问openmv文件系统解决办法 openmv USB功能改动 openmv驱动被更改如何修复

我之前误打误撞遇到一次&#xff0c;直接把openmv的全部端口删除卸载然后重新插上就会自动重新装上一个openmv端口修复成功&#xff0c;大家可以先试试不行再用下面的方法 全部卸载再重新插拔openmv 要解决OpenMV IDE中出现的两个端口问题&#xff0c;可以尝试以下步骤&#x…

LabVIEW双光子成像系统:自主创新,精准成像,赋能科研

双光子成像系统&#xff1a;自主创新&#xff0c;精准成像&#xff0c;赋能科研 第一部分&#xff1a;概述 双光子成像利用两个低能量光子同时激发荧光分子&#xff0c;具有深层穿透、高分辨率、低光损伤等优势。它能实现活体深层组织的成像&#xff0c;支持实时动态观察&…

Deepseek-R1 和 OpenAI o1 这样的推理模型普遍存在“思考不足”的问题

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Vue3学习笔记-Vue开发前准备-1

一、安装15.0或更高版本的Node.js node -v npm -v 二、创建Vue项目 npm init vuelatest 三、Vue项目结构 node_modules: Vue项目运行的依赖文件public&#xff1a;资源文件夹package.json&#xff1a;信息描述文件

数据结构:时间复杂度

文章目录 为什么需要时间复杂度分析&#xff1f;一、大O表示法&#xff1a;复杂度的语言1.1 什么是大O&#xff1f;1.2 常见复杂度速查表 二、实战分析&#xff1a;解剖C语言代码2.1 循环结构的三重境界单层循环&#xff1a;线性时间双重循环&#xff1a;平方时间动态边界循环&…

S4 HANA明确税金汇差科目(OBYY)

本文主要介绍在S4 HANA OP中明确税金汇差科目(OBYY)相关设置。具体请参照如下内容&#xff1a; 1. 明确税金汇差科目(OBYY) 以上配置点定义了在外币挂账时&#xff0c;当凭证抬头汇率和税金行项目汇率不一致时&#xff0c;造成的差异金额进入哪个科目。此类情况只发生在FB60/F…

87.(3)攻防世界 web simple_php

之前做过&#xff0c;回顾 12&#xff0c;攻防世界simple_php-CSDN博客 进入靶场 <?php // 显示当前 PHP 文件的源代码&#xff0c;方便调试或查看代码结构 // __FILE__ 是 PHP 的一个魔术常量&#xff0c;代表当前文件的完整路径和文件名 show_source(__FILE__);// 包含…

pycharm 中的 Mark Directory As 的作用是什么?

文章目录 Mark Directory As 的作用PYTHONPATH 是什么PYTHONPATH 作用注意事项 Mark Directory As 的作用 可以查看官网&#xff1a;https://www.jetbrains.com/help/pycharm/project-structure-dialog.html#-9p9rve_3 我们这里以 Mark Directory As Sources 为例进行介绍。 这…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户注册

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;项目基本介绍 &#x1f6a6;项…

Microsoft Power BI:融合 AI 的文本分析

Microsoft Power BI 是微软推出的一款功能强大的商业智能工具&#xff0c;旨在帮助用户从各种数据源中提取、分析和可视化数据&#xff0c;以支持业务决策和洞察。以下是关于 Power BI 的深度介绍&#xff1a; 1. 核心功能与特点 Power BI 提供了全面的数据分析和可视化功能&…

[SAP ABAP] 在ABAP Debugger调试器中设置断点

在命令框输入/H&#xff0c;点击回车以后&#xff0c;调试被激活&#xff0c;点击触发任意事件进入ABAP Debugger调试器界面 点击按钮&#xff0c;可以在Debugger调试器中新增临时断点 我们可以从ABAP命令、方法、功能、表单、异常、消息、源代码等多个维度在Debugger调试器中设…

【NEXT】网络编程——上传文件(不限于jpg/png/pdf/txt/doc等),或请求参数值是file类型时,调用在线服务接口

最近在使用华为AI平台ModelArts训练自己的图像识别模型&#xff0c;并部署了在线服务接口。供给客户端&#xff08;如&#xff1a;鸿蒙APP/元服务&#xff09;调用。 import核心能力&#xff1a; import { http } from kit.NetworkKit; import { fileIo } from kit.CoreFileK…

RssWebAll:抓取任意网页的内容生成 RSS 订阅源

RssWebAll&#xff1a;抓取任意网页的内容生成 RSS 订阅源 RssWebAll 是一个强大的工具&#xff0c;可以帮助用户抓取任意网页的内容&#xff0c;并生成相应的 RSS 订阅源&#xff0c;让用户随时随地获取他们感兴趣的内容更新。 功能亮点 简单易用&#xff1a;所见即所得&…

从一到无穷大 #43:Presto History Based Optimizer,基于PlanNode粒度统计的查询计划选择策略

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言MotivationArchitectureHBO ScenarioExperiments结束语 引言 过年回家这件事在挚…

【C++】继承(下)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的继承&#xff08;下&#xff09;&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 5.继承与友元6.继承与静态成员7.复杂的菱形继承及菱形虚拟继承8.继…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(九)(完结篇)

文章目录 一、成绩查询模块实现1、学生成绩查询功能实现1.1 页面设计1.2 前端页面实现1.3 后端功能实现2、成绩分段查询功能实现2.1 页面设计2.2 前端页面实现2.3 后端功能实现二、试卷练习模块实现三、我的分数模块实现1、 页面设计2、 前端页面实现3、 后端功能实现四、交流区…