vector函数介绍与实现(迭代器失效)

 

目录

一、介绍vector 

1.vector是什么 

2.vector的特点 

1.随机访问 

2.缓存命中

 3.vector的结构

 二、vector的函数

1.构造函数(创建)​编辑

 2.Iterator(迭代器)

 3.Capacity(容量)

三、迭代器失效

四、实现vector


一、介绍vector 

1.vector是什么 

vector是C++中STL(Standard Template Library)提供的一个容器类,它是一个动态数组,能够存储同一类型的元素。

vector是STL容器中一种常用的容器,和数组类似,由于其大小 (size)可变,常用于数组大小不可知的情况下来替代数组。vector是为了实现动态数组而产生的容器。

这里是官网vector - C++ 参考 (cplusplus.com)可以进行详细的了解

2.vector的特点 

1.随机访问 

 vector是一种顺序容器,在内存中连续排列,因此可以通过下标快速访问,时间复杂度为O(1)。然而,连续排列也意味着大小固定,数据超过vector的预定值时vector将自动扩容。

2.缓存命中

对于我们需要寻找的元素,可以通过下标快速确定位置 

 3.vector的结构

 如图所示,vector内部有三个指针,分别指向数据块的开始、有效数据的结尾、存储容量的结尾

_start : 指向数据块的开始

_finish : 指向有效数据的结尾

_endofstorage : 指向存储容量的结尾

_finish - _start  :数据有效元素的个数

_endofstorage - _start  :开辟空间的大小——数组的大小

_endofstorage - _finish :除有效数据外,剩余空间的大小

 二、vector的函数

 本文对于使用只是带大家了解底层函数参数,具体使用不过多介绍。相信大家可以自己搞明白!

1.构造函数(创建)

解释一下关键字 explicit 

不要把 explicit 误认为是返回值类型,它在 c++ 中是关键字用于防止不应该允许的隐式类型转换

 

如这段代码,explicit关键字阻止了 int 到 MyClass 的隐式转换 

 allocator_type是分配器类型,用于控制容器中元素的存储和回收。不做过多介绍

 2.Iterator(迭代器)

begin:返回开始的位置

end:返回结尾的位置 

r:反向迭代器

c:const 迭代器 (不能改变指针指向的内容,但可以改变指针本身)

 3.Capacity(容量)

这些是基本的函数,需要了解之后才能去进行 增删查改 的操作,对于增删查改,不进行介绍,建议大家去官方网站自己学习  vector - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/vector/vector/?kw=vector

三、迭代器失效

因为会发生扩容,即申请新的空间,所以原指针会失效。

使用while循环直接赋值,则可以避免浅拷贝问题!

四、实现vector

注意:实现时复用了已经实现的函数! 

#include<iostream>
#include<stdio.h>
#include<assert.h>
using namespace std;
#include<string.h>

namespace bit
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;

		vector()
		{}
		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = nullptr;
				_finish = nullptr;
				_endofstorage = nullptr;
			}

		}

		vector(int n, const T& value = T())
		{
			resize(n, value);
		}
		vector(const vector<T>& v)
		{
			/*_start = new T[v.capacity()];
			memcpy(_start, v._start, v.size() * sizeof(T));
			_finish = _start + v.size();
			_endofstorage = _start + v.capacity();*/
			reserve(v.capacity());
			for (const auto& e : v)
			{
				push_back(e);
			}

		}
		vector<T>& operator= (vector<T> v)
		{
			swap(v);
			return *this;
		}
		
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		

		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		iterator begin() const
		{
			return _start;
		}
		iterator end() const
		{
			return _finish;
		}
		const_iterator cbegin() const
		{
			return _start;
		}
		const_iterator cend() const
		{
			return _finish;
		}

		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity);
			}
			*_finish = x;
			++_finish;
		}
		void pop_back()
		{
			assert(size() > 0);
			--_finish;
		}


		iterator insert(iterator pos, const T& x)
		{
			assert(pos <= _finish && pos >= _start);
			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);//扩容pos会失效
				pos = _start + len;
			}
			iterator it = _finish - 1;
			while (it >= pos)
			{
				*(it + 1) = *it;
				--it;
			}

			*pos = x;
			++_finish;

			return pos;
		}
		
		iterator erase(iterator pos)
		{
			assert(pos < _finish);
			assert(pos >= _start);
			iterator it = pos + 1;
			while (it<_finish)
			{
				*(it - 1) = *it;
				++it;
			}
			_finish--;

			return pos + 1;
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);
		}
		size_t size() const
		{
			return _finish - _start;
		}
		size_t capacity() const
		{
			return _endofstorage - _start;
		}

		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}
		const T& operator[](size_t pos) const
		{
			assert(pos < size());
			return _start[pos];
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old = size();
				T* tmp = new T[n];
				if (_start)
				{
					//memcpy(tmp, _start, n * sizeof(T));
					for (size_t i = 0; i < old; i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start + old;
				_endofstorage = _start + n;
			}
		}

		void resize(size_t n, const T& value = T())
		{
			if (n > size())
			{
				reserve(n);
				while (_finish < _start + n)
				{
					*_finish = value;
					++_finish;
				}
			}
			else
			{
				_finish = _start + n;
			}
		}

	private:
		iterator _start= nullptr;// 指向数据块的开始
		iterator _finish= nullptr;// 指向有效数据的尾
		iterator _endofstorage= nullptr;// 指向存储容量的尾
	};
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库性能优化的解决方案

目录​​​​​​​ 1、什么是数据库性能优化 1.1 数据库性能优化的概念 1.2 为何需要进行数据库性能优化 1.3 数据库性能优化的好处 2、数据库性能优化的基本原理 2.1 数据库查询优化 2.2 数据库索引优化 2.3 数据库表结构优化 2.4 数据库硬件优化 3、数据库查询优化…

一个好用的服务器控制面板

简介 它是一个免费开源的管理面板工具&#xff0c;可以帮助你集中管理多个服务器和网站。Ajenti 支持 Linux、BSD、Mac OS X和Windows 等多个操作系统&#xff0c;并且可以通过一个直观的 Web 界面来完成各种系统管理任务。 相比于其他管理面板&#xff0c;Ajenti有以下几个优…

go语言数组和切片

1. 数组Array Golang Array和以往认知的数组有很大不同。 1. 数组&#xff1a;是同一种数据类型的固定长度的序列。2. 数组定义&#xff1a;var a [len]int&#xff0c;比如&#xff1a;var a [5]int&#xff0c;数组长度必须是常量&#xff0c;且是类型的组成部分。一旦定义&…

数字主持人有多少种应用方式?

在数字经济时代下&#xff0c;越来越多企业、品牌以数字人进行新闻资讯报道、主持互动、人机交互等多形式&#xff0c;提升企业、品牌的影响力和认知度。 *图片源于网络 如山东广播电视台数字主持人“海蓝”&#xff0c;不仅可以用大会活动现场&#xff0c;用多国语言与主持人、…

从零开始c++精讲:第四篇——模板初阶

文章目录 一、泛型编程二、函数模板2.1函数模板概念2.2函数模板格式2.3函数模板原理2.4函数模板实例化2.5函数模板匹配原则 三、类模板3.1类模板的定义格式3.2类模板的实例化 一、泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& righ…

ios适配虚拟home键

在H5开发过程中遇到一个兼容性问题。iphone手机的虚拟home键会对屏幕底部的内容造成遮挡。要处理此问题&#xff0c;需要清楚安全区域这个概念。 安全区域 根据刘海和虚拟Home键&#xff0c;Apple为其设备提供了屏幕安全区域的视觉规范 竖屏&#xff1a;竖屏的时候&#xff…

基于springboot在线学习平台源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括学习平台的网络应用&#xff0c;在外国学习平台已经是很普遍的方式&#xff0c;不过国内的管理平台可能还处于起步阶段。学习平台具有学习信息管理功能的选择。学习平台采用ja…

PWN入门Protostar靶场Stack系列

Protostar靶场地址 https://exploit.education/protostar/溢出 源码分析 #include <stdlib.h> #include <unistd.h> #include <stdio.h>int main(int argc, char **argv) {volatile int modified; //定义一个变量char buffer[64]; //给…

C++:优先队列-Priority_queue

目录 1.关于优先队列 2.priority_queue的使用 1.构造方法 2.empty();判空 3.size(); 4.top(); 5.push(val); 6.pop(); 3.优先队列模拟实现 4.用优先队列解决数组中第K个大的元素 1.关于优先队列 在C中&#xff0c;可以使用STL&#xff08;标准模板库&#xff09;中的p…

软件测试的调用接口怎么调用,逻辑是什么?

一、什么是接口测试&#xff1f; 接口测试是测试系统组件之间接口的测试。接口主要用于检测外部系统和内部子系统之间的交互点。测试的重点是检查数据交换、传输、控制和管理过程&#xff0c;以及系统之间的相互逻辑依赖。 二、为什么要做接口测试&#xff1f; 在淘宝系统的…

SpringBoot使用Swagger2生成接口文档

一、导入依赖 <!-- knife4j--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version></dependency> 二、配置类 通过一下配置&am…

【并发编程】活锁

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程 ⛺️稳重求进&#xff0c;晒太阳 活锁 定义&#xff1a;活锁出现在两个线程互相改变对象的结束条件&#xff0c;最后谁也无法结束 代码示例 public class TestLiveLock {stati…

java web mvc-03-JFinal

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails JFinal JFinal 是基于 Java 语言的极…

策略模式在AIBOT项目中的实际应用

原文链接https://www.jylt.cc/#/detail?activityIndex2&id8d1912358fa1c1d8db1b44e2d1042b70AIBOT 你想 我来做AIBOThttps://chat.jylt.top/ 定义 策略模式&#xff08;Strategy Pattern&#xff1a;Define a family of algorithms,encapsulate each one,and make them …

生成芭比系列咒语

咒语&#xff1a;Close-up of a man with golden hair and a necklace,Digital Art Inspired by Cheng Yanjun, Tumblr,Rococo,Portrait of Josie in Black Pink,Portrait Zhixiu Black Pink,flowing golden hair,long flowing golden hair,Bubble Gum Long Hair,blond hair,Pi…

电信联通5G共建共享方案实施及验证

一、情况概述 随着2019年9月9日中国电信集团与联通签署《5G网络共建共享框架合作协议书》&#xff0c;电信与联通在全国范围内合作共建5G接入网络。根据合作协议&#xff0c;联通运营公司将与中国电信在全国范围内合作共建一张5G接入网络, 双方划定区域&#xff0c;分区建设&a…

前端开发中的那些规范

开发中的那些规范 俗话说&#xff1a;无规矩不成方圆。生活如此、软件开发也如此。 来聊一聊开发中有哪些地方需要规范。 为什么需要规范 现在开发一个应用基本上都是多人协作&#xff0c;一旦涉及到多人&#xff0c;必然不同的开发者的开发习惯、编码方式都是有所不同的&…

SpringBoot整合ElasticSearch实现基础的CRUD操作

本文来说下SpringBoot整合ES实现CRUD操作 文章目录 概述spring-boot-starter-data-elasticsearch项目搭建ES简单的crud操作保存数据修改数据查看数据删除数据 本文小结 概述 SpringBoot支持两种技术和es交互。一种的jest&#xff0c;还有一种就是SpringData-ElasticSearch。根据…

【C语言入门】交换两个变量的值(三种方法)

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;C语言 个人主页&#xff1a;Celias blog~ 引言 我们在编写程序时&#xff0c;经常会需要交换两个变量的值&…

Shell脚本③条件语句、if命令和case命令

目录 一.条件语句 1.test测试条件表达式 2.整数数值比较 &#xff08;1&#xff09;比较两个整数大小 &#xff08;2&#xff09;查看系统剩余内存是否低于1024M 3.逻辑测试 4.三元运算符 二.if命令 1.单分支结构 2.双分支结构 3.多分支结构 三.case语句 四.脚本 …