STL之vector(讲解迭代器失效,拷贝构造函数等现代版写法)

还是老规矩,直接上代码:

#pragma once
#include "riterator.hpp"
#include <iostream>
#include <assert.h>
#include <set>
#include <map>
using namespace std;
namespace cc
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;vector(): _start(new T[4]), _finish(_start), _end_of_strag(_start+4){}template<class Iterator>vector(Iterator begin,Iterator end): _start(new T[4]), _finish(_start), _end_of_strag(_start+4){//同样,这里最好不要用memcpy等函数(涉及深浅拷贝问题)while(begin!=end){push_back(*begin);begin++;}}vector(const vector<T>& d): _start(nullptr), _finish(nullptr), _end_of_strag(nullptr){vector<T> tem(d.begin(),d.end());swap(tem);}~vector(){delete[] _start;_start=_finish=_end_of_strag=nullptr;}vector<T>& operator=(vector<T> d){swap(d);return *this;}void swap(vector<T>& d){std::swap(_start,d._start);std::swap(_finish,d._finish);std::swap(_end_of_strag,d._end_of_strag);}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}size_t size()const{return _finish-_start;}size_t capacity()const{return _end_of_strag-_start;}T& operator[](size_t x)const{assert(x<size());return _start[x];}void resize(size_t n,const T& x=T()){_finish=_start+n;for(size_t i=0;i<n;i++)_start[i]=x;}void reserve(size_t n){if(n>size()){iterator tem=new T[n];//这里最好不要用memcpy等函数(涉及深浅拷贝问题)for(size_t i=0;i<size();i++)tem[i]=_start[i];size_t ret=_finish-_start;delete[] _start;_start=tem;_end_of_strag=_start+n;_finish=_start+ret;}}void push_back(const T& x){if(size()==capacity())reserve(2*capacity());_start[_finish-_start]=x;_finish++;}        private:iterator _start;iterator _finish;iterator _end_of_strag;  };
}

很简单的一个容器,其实 本质原理就是类似于顺序表,在这里我并没有实现所有的功能,但是主要的功能都已经实现,顺序表我想大家应该都是比较熟悉的,所以这里就不讲实现的原理了,来说说这里最主要的一个问题。

vector最主要的问题是什么呢?其实就是深浅拷贝和迭代器的失效。

1.深浅拷贝的问题

这个很容易就写错了,哪怕拷贝构造函数等写的是深拷贝,但是如果再reserve这个函数内部一不注意就会出现浅拷贝的问题,注释中已经说明,这里不再多说,这个还是比较简单的。如果不知道自己实现的vector是否完成深拷贝,可以自己建造一个二维数组来试试

2.迭代器失效

迭代器失效在vector中有大两种:分别是插入,删除

插入导致迭代器失效:插入其实又有两种迭代器失效的可能,一种是插入的时候,需要扩容,此时如果一不小心就会到直接迭代器直接失效,其次就是在任意地方插入的时候,会导致迭代器失效的可能。

扩容导致迭代器失效原理:

我们可以看看下面的代码:

     //正确版// void reserve(size_t n)// {//     if(n>size())//     {//         iterator tem=new T[n];//         //这里最好不要用memcpy等函数(涉及深浅拷贝问题)//         for(size_t i=0;i<size();i++)//             tem[i]=_start[i];//         size_t ret=_finish-_start;//         delete[] _start;//         _start=tem;//         _end_of_strag=_start+n;//         _finish=_start+ret;//     }// }//错误版void reserve(size_t n){if(n>size()){iterator tem=new T[n];for(size_t i=0;i<size();i++)tem[i]=_start[i];delete[] _start;_start=tem;//经典错误出现的地方_finish=_start+size();_end_of_strag=_start+n;}}

为什么说这里有错误呢?两个看起来其实感觉也差不多,但为什么下面的是错误的呢?其实很好理解,因为在这里你的_finish=_start+size(),这里是不能加size()的,因为size的内部实现返回的是__finish-_start,但是此时的_start指向的是tem的空间,并且把原来的空间已经给释放了,所以此时会出现问题。

其次就是任意位置插入会导致迭代器失效原理:如下图:

 我们可以看到的是,我在3这里插入了7,把所有的数后移了一位,但是,我们可以看到的是,此时原本3这个位置的数变成了7,但是迭代器的位置其实没有变,所以此时你如果不更新迭代器的话,就到导致迭代器的失效。

删除导致迭代器的失效:

原理其实和插入差不多,都是原本位置上的数改变,而迭代器的位置没有改变,所以此时要更新迭代器,原理和插入导致的迭代器失效其实是一样的。大家可以仔细想想

还有就是拷贝构造和赋值运算符的重载的现代版写法,其实个人建议的是,如果理解不了现代版的写法,可以按照深拷贝的思路来慢慢写,现代版的实现只不过是代码比较简洁而已,不过还是看个人喜好了,现代版的实现提高了成员函数的耦合性(个人认为不好的一点),如果出现错误的,维修成本比较大,而原始的写法就没有这种问题。

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

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

相关文章

Node基础--Node简介以及安装教程

1.Node简介 Node.js发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;使用了一个事件驱动、非阻塞式I/O模型&#xff0c;让JavaScript 运行在服务端的开发平台&#xff0c;它让JavaScript成为与PHP、Python、Pe…

静态代码扫描工具 Sonar 配置及使用

概览 Sonar 是一个用于代码质量管理的开放平台。通过插件机制&#xff0c;Sonar 可以集成不同的测试工具&#xff0c;代码分析工具&#xff0c;以及持续集成工具。与持续集成工具&#xff08;例如 Hudson/Jenkins 等&#xff09;不同&#xff0c;Sonar 并不是简单地把不同的代…

B树和B+树MySQL为什么用B+树?

文章目录 B树和B树B树B树的定义B树的插入操作删除操作 B树B树的定义B树的插入操作删除操作 B树和B树的区别?MySQL数据库为啥用B树作为索引&#xff0c;而不用B树? B树和B树 原文链接&#xff1a;https://blog.csdn.net/jinking01/article/details/115130286 B树 B树的定义…

变色树脂T-46CC详解

一、产品介绍 Tulsimer T-46 CC 是一款专门研制的、优质的、强酸型的聚苯乙烯架构的阳离子交换树脂&#xff0c;具有核子级磺酸官能团&#xff0c; 并同时拥有绝佳的物理及化学稳定品质&#xff0c;因此广泛应用于水处理当中。 Tulsimer T-46 CC 主要用于水净化处理&#xff…

智慧党建VR虚拟3D数字化展厅发展和传承传统文化

三维全景虚拟现实技术应用在虚拟展馆中&#xff0c;主要是通过全景照片的虚拟与建模&#xff0c;营造出三维虚拟仿真的场景&#xff0c;从而结合展馆展示的需求&#xff0c;营造出更加有效的氛围&#xff0c;起到优化展示效果的作用。 三维全景虚拟现实技术的应用&#xff0c;能…

Java【手撕双指针】LeetCode 611. “有效三角形个数“, 图文详解思路分析 + 代码

文章目录 前言一、有效三角形个数1, 题目2, 思路分析1, 从左往右 or 从右往左?3, 代码展示 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 &#x1…

BootstrapBlazor组件使用:数据注解

文章目录 前言BB数据注解数据注解源码数据注解简介注解简单实例[BB 编辑弹窗](https://www.blazor.zone/edit-dialog)[ValidateForm 表单组件](https://www.blazor.zone/validate-form)使用简介 前言 BootstrapBlazor(一下简称BB)是个特别好用的组件&#xff0c;基本上满足了大…

jupyter notebook出现ERR_SSL_VERSION_OR_CIPHER_MISMATCH解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

软件测试架构师在实际工作中都做哪些事情呢?

软件测试架构师在实际工作中&#xff0c;都做哪些事情呢&#xff1f; 一家业务体系庞大、复杂的公司的测试架构师的职责主要有五个&#xff1a; 1、测试团队的技术带头人 测试架构师会关注整个团队的技术提升&#xff0c;包括技术难题的攻关&#xff0c;团队遇到的技术难题&…

(6)(6.3) 自动任务中的相机控制

文章目录 前言 6.3.1 概述 6.3.2 自动任务类型 6.3.3 创建合成图像 前言 本文介绍 ArduPilot 的相机和云台命令&#xff0c;并说明如何在 Mission Planner 中使用这些命令来定义相机勘测任务。这些说明假定已经连接并配置了相机触发器和云台(camera trigger and gimbal ha…

ORB-SLAM2报错集合(数据集测试系列1)

目录 错误1 错误2 错误3 错误4 错误5 错误6 错误7 错误8 TUM-RGBD测试 KITTI测试 EuRoC测试 写在前面~ ORB-SLAM2 github链接&#xff1a;GitHub - electech6/ORB_SLAM2_detailed_comments: Detailed comments for ORB-SLAM2 with trouble-shooting, key formula …

QChart:数据可视化(用图像形式显示数据内容)

1、数据可视化的图形有&#xff1a;柱状/线状/条形/面积/饼/点图、仪表盘、走势图&#xff0c;弦图、金字塔、预测曲线图、关系图、数学公式图、行政地图、GIS地图等。 2、在QT Creator的主页面&#xff0c;点击 欢迎》示例》右侧输入框 输入Chart&#xff0c;即可查看到QChar…

回归预测 | MATLAB实现SSA-RF麻雀搜索优化算法优化随机森林算法多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现SSA-RF麻雀搜索优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现SSA-RF麻雀搜索优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;…

数据结构—排序

8.排序 8.1排序的概念 什么是排序&#xff1f; 排序&#xff1a;将一组杂乱无章的数据按一定规律顺序排列起来。即&#xff0c;将无序序列排成一个有序序列&#xff08;由小到大或由大到小&#xff09;的运算。 如果参加排序的数据结点包含多个数据域&#xff0c;那么排序往…

Ubuntu18.04 交叉编译curl-7.61.0

下载 官方网址是&#xff1a;curl 安装依赖库 如果需要curl支持https协议&#xff0c;需要先交叉编译 openssl,编译流程如下&#xff1a; Ubuntu18.04 交叉编译openssl-1.1.1_我是谁&#xff1f;&#xff1f;的博客-CSDN博客 解压 # 解压&#xff1a; $tar -xzvf curl-7.61.…

【Go】Goland项目配置运行教程

Golang项目配置运行教程 1.安装Golang下载安装包安装 2.Goland配置2.1 环境2.2 goland配置2.2.1 没有makefile的情况2.2.2 有makefile的情况 3.跨平台项目4.补充 注意&#xff0c;本项目描述的是git clone下来的Golang项目配置运行教程&#xff0c;并不是从头创建一个Golang项目…

redis常用五种数据类型详解

目录 前言&#xff1a; string 相关命令 内部编码 应用场景 hash 相关命令 内部编码 应用场景 list 相关命令 内部编码 应用场景 set 相关命令 内部编码 应用场景 Zset 相关命令 内部编码 应用场景 渐进式遍历 前言&#xff1a; redis有多种数据类型&…

Cookie 和 Session 的工作流程

目录 一、Cookie是什么&#xff1f; 二、Session是什么? 三、Cookie的工作流程 四、Session的工作流程 五、Session和Cookie的区别和联系 一、Cookie是什么&#xff1f; Cookie是一种在网站和用户之间交换信息的机制。它是由Web服务器发送给用户浏览器的小型文本文件&#xff…

【leetcode 力扣刷题】反转链表+递归求解

反转链表递归求解 206. 反转链表解法①&#xff1a;取下一个节点在当前头节点前插入解法②&#xff1a;反转每个节点next的指向解法③&#xff1a;递归 92.反转链表Ⅱ反转left到right间节点的next指向 234.回文链表解法①&#xff1a;将链表元素存在数组中&#xff0c;在数组上…

解决idea登录github copilot报错问题

试了好多方案都没用&#xff0c;但是这个有用&#xff0c; 打开idea-help-edit custonm vm options 然后在这个文件里面输入 -Dcopilot.agent.disabledtrue再打开 https://github.com/settings/copilot 把这个设置成allow&#xff0c;然后重新尝试登录copilot就行就行 解决方…