C++vector及其实现

第一个参数是类型(可以是自定义也可以是内置类型)   

相当于生成一个该类型的数组    

allocator是空间配置器

遍历

1.下标遍历

2.迭代器遍历

3.范围for

对象访问

有名对象访问

匿名对象访问

隐式类型转换

成员函数

sort

使用sort需要包含头文件algorithm

eg.

sort的使用非常灵活,只需要在前两个参数限定范围就可以实现范围排序

eg.

最后面的参数是仿函数,是用来进行数据比较的

使用sort默认是升序,如果要降序,可以

greater就是重载">"运算符

同时sort也可以用来排序自定义类型,但是需要自行重载">"和"<",或者自行写仿函数

insert

finish指向最后有效数据的后一位

迭代器失效

经过扩容后会导致迭代器失效

因为扩容本质是开一段新的空间,而pos还是指向旧的已经被释放的空间,则pos是野指针

因此如果要再次使用迭代器,需要堆迭代器进行更新

erase

erase之后,我们通常认为迭代器失效

因为删除数据后,较小可能存在缩容,导致空间改变

导致迭代器失效

就算不缩容,如果删除最后一个数据

此时再去访问迭代器,就是一种越界访问

因此我们认为erase后迭代器失效

对于失效的迭代器,vs做了强制的检查,防止迭代器失效

eg.

错误:

正确:

find

除去string,其他的类型的find函数被包在算法头文件algorithm中

find函数返回该数据的位置,如果没找到就返回最后一个位置

拷贝构造

没有写拷贝构造编译器会默认生成拷贝构造,

默认的浅拷贝拷贝构造可以实现拷贝,但是无法实现赋值

构造函数

1.

2.

eg.

多参数构造的隐式类型转换

initializer list

它是一个类模板

它是一个常量数组,其中存在两个指针,指向数组的开始和结束

初始化方式

string数组的问题

尾插1次后

没有问题

但是,再多push_back后

起初有4块空间,memcpy对任意类型都是浅拷贝

reserve后,由于是浅拷贝

新旧空间指向同一空间

但是由于reserve是释放旧空间

导致旧空间被释放,导致前4组指针是野指针

解决方法

1.写深拷贝

模拟实现


#pragma once
#include<assert.h>
namespace bit 
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		//类模板的成员函数
		//函数模板--目的是支持任意容器的迭代器区间初始化
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		vector(size_t n, const T& val = T())//缺省值给T()(匿名对象)初始化,适用于任何类型
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}

		vector(initializer_list<T> il)
		{
			reserve(il.size());
			for (auto e : il)
			{
				push_back(e);
			}
		}
		//强制编译器生成默认的构造函数
		vector() = default;
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto e : v)
			{
				push_back(e);
			}
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_capacity, v._capacity);
		}
		vector<T>& operator=(vector<T> v)
		{
			this->swap(v);
			return *this;
		}

		void reserve(size_t n)//参数为需要扩为多大
		{
			if (n > capacity())
			{
				size_t oldsize = size();
				T* tmp = new T[n];
				if (_start)
				{
					/*memcpy(tmp, _start, sizeof(T) * size());*/
					for (size_t i = 0; u < oldsize; i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start + oldsize;
				_end_of_storage = _start + n;
			}
		}

		size_t capacity()
		{
			return _end_of_storage - _start;
		}

		size_t size()
		{
			return _finish - _start;
		}

		T& operator[](size_t i)
		{
			assert(i < size());

			return _start[i];
		}

		void push_back(const T& x)
		{
			if (_finish == _end_of_storage)
			{
				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 >= _start);
			assert(pos <= _finish);

			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;

				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity);

				pos = _start + len;
			}

			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;

			return pos;
		}

		void erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);

			iterator it = pos + 1;
			while (it != _finish)
			{
				*(it - 1) = *it;
				++it;
			}
			--_finish;
		}

	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _end_of_storage = nullptr;
	};

	void test_vector1()
	{
		bit::vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

		v1.insert(v1.begin() + 1, 2005);
		//for (size_t i = 0; i < v1.size(); i++)
		//{
		//	cout << v1[i] << " ";//应该用不了,但是在test中上面展开了包含了头文件,所以可以用
		//}
		//cout << endl;
		v1.erase(v1.begin());
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		//vector<int>::iterator it = v1.begin();
		//while (it != v1.end())
		//{
		//	cout << *it << " ";
		//	++it;
		//}
		//cout << endl;
		
	}
}

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

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

相关文章

QA 未能打开位于 D:/Computer999/Computer999.vbox 的虚拟电脑

前言 未能打开位于 xxx/Computer999.vbox 的虚拟电脑&#xff0c;并提示E_INVALIDARG (0X80070057)&#xff0c;是最常见的一个错误&#xff0c;下面是解决办法。 内容 1、提示下面的错误&#xff0c;注册Computer999失败&#xff1a; 未能打开位于 D:/Computer999/Compute…

【刷题(15】普通数组

一 普通数组基础 首先&#xff0c;我们根据下图先了解一下什么是前缀和。 既然我们明白了前缀和是怎么回事&#xff0c;那我们就来看一下我们该怎么输入 先给出答案&#xff0c;然后再给出分析。 答案&#xff1a; for (int i 1; i < n; i ){cin >> a[i];s[i] s…

JVM之垃圾回收面试总结

文章目录 1.GC概述1.1 什么是垃圾1.2 为什么需要GC&#xff1f;1.3 早期垃圾回收1.4 Java垃圾回收机制1.5 评估GC的性能指标 2.垃圾回收相关算法2.1 垃圾标记阶段的算法2.1.1 引用计数算法(Java没有使用)2.1.2 可达性分析算法 2.2 垃圾清除阶段的算法2.2.1 标记-清除(Mark-Swee…

今在推特发一个推特立马推特账户被删除了

咨询 Google Contacts 是如何 获取我的苹果手机通讯录的电话号码清单的&#xff1f;不到一分钟&#xff0c;我的账户之间被删除了&#xff0c;比停用、冻结还令人可怕。 立马推特账户被删除了。

阿里云搭建物联网平台+MQTT.fx接入阿里云

文章目录 本篇介绍一、阿里云物联网平台搭建二 、MQTT客户端接入阿里云物联网平台总结 本篇介绍 本篇搭建了阿里云物联网平台&#xff0c;使用MQTT.fx接入阿里云&#xff0c;上传温湿度数据 使用到的软件&#xff1a;阿里云、MQTT.fx 一、阿里云物联网平台搭建 首先创建一个物…

Codeforces Round 949 (Div. 2)(A,B题解)

这场真是给我打的汗流浃背了&#xff0c;这场真的巨难&#xff08;可能是因为我二进制根本就没学好的原因吧&#xff09; 反正总共就搞了两道题&#xff0c;第一道题注重于思维&#xff0c;第二道题纯二进制&#xff0c;第三道题看着也是二进制&#xff08;最后时间不够了&…

【Microelectronic Systems】

1 background&introduction 2 analog to Digital Conversion 3 Digital to Anolog Conversion 4 introduction to CMOS outlook ! introduction to semiconductors siemens,西门子 properties of semiconductors types of semiconductors $ PN junction 5 Mathematic s…

Llama(二):Open WebUI作为前端界面,使用本机的llama3

目录 背景 Open WebUI是什么 工程能力特性 产品功能特性 用户体验特性 Open WebUI安装并使用 背景 Mac M1芯片&#xff0c;16G 内存 llama3 8B的部署参考Llama&#xff08;一&#xff09;&#xff1a;Mac M1芯片运行Llama3-CSDN博客在Mac M1 16G内存环境中&#xff0c;…

【数据结构】二叉树的层序遍历~动画超详解

目录 1 什么是层序遍历2 二叉树层序遍历的基本思路3 二叉树层序遍历的实现 1 什么是层序遍历 我们从字面意思就明白,所谓层序,就是一层一层按顺序去遍历一个二叉树,这和我们之前了解的按前中后序遍历方式完全不同 比方说这颗二叉树: 前序遍历: 层序遍历: 2 二叉树层序遍历的…

Zabbix安装:构建高效可靠的Zabbix监控系统

目录 引言 一、zabbix基本介绍 &#xff08;一&#xff09;什么是zabbix &#xff08;二&#xff09;zabbix结构体系 &#xff08;三&#xff09;zabbix监控对象 &#xff08;四&#xff09;zabbix进程 &#xff08;五&#xff09;zabbix监控模式 &#xff08;六&#…

VRTK4教程 二:基本追踪

文章目录 untiyXR和UnityXRPluginFramwork使用方法&#xff1a; TrackedAlias使用方法使用技巧 untiyXR和UnityXRPluginFramwork 这两个用于跟踪头盔位置&#xff0c;其中UnityXR使用的是旧版API&#xff0c;另一个是新版API&#xff0c;两个我我们选一个即可 使用方法&#…

git使用流程

1.下载git 搜索下载 2.注册github账号&#xff08;打开爬墙工具&#xff09; 创建一个仓库 3.配置邮箱和密码 4.所以找一个文件夹 鼠标右键 选择 open Git Bash here&#xff08;当前文件夹下打开命令行&#xff09; 输入命令 配置用户名和邮箱 5.将建的仓库克隆下来 …

鸿蒙Ability Kit(程序框架服务)【UIAbility组件与UI的数据同步】

UIAbility组件与UI的数据同步 基于当前的应用模型&#xff0c;可以通过以下几种方式来实现UIAbility组件与UI之间的数据同步。 [使用EventHub进行数据通信]&#xff1a;在基类Context中提供了EventHub对象&#xff0c;可以通过发布订阅方式来实现事件的传递。在事件传递前&am…

响应式UI组件DevExtreme中文教程 - 工具栏的自适应模式

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

【算法】在?复习一下快速排序?

基本概念 快速排序是一种基于交换的排序算法&#xff0c;该算法利用了分治的思想。 整个算法分为若干轮次进行。在当前轮次中&#xff0c;对于选定的数组范围[left, right]&#xff0c;首先选取一个标志元素pivot&#xff0c;将所有小于pivot的元素移至其左侧&#xff0c;大于…

Java实战:文本文件复制

任务目标 本实战任务的目标是创建一个Java程序&#xff0c;用于复制指定的文本文件到另一个位置&#xff0c;并在控制台中显示复制结果。 任务步骤 创建源文件&#xff1a;在指定的路径D:\love.txt创建源文件。创建文件复制类&#xff1a;在net.huawei.student.test包中创建…

上位机图像处理和嵌入式模块部署(f407 mcu中的单独烧录方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;stm32有三种烧录方法&#xff0c;一种是st-link v2&#xff0c;一种是dap&#xff0c;一种是j-link。不过我们在实际操作…

数电课设:电动机转速测量控制电路

电动机转速测量控制电路设计 摘要 本文设计的电动机转速测量控制电路通过数字电路核心实现对电机转速的测量和显示。与市面上基于单片机的电机转速测量相比&#xff0c;该电路无需要注重复杂的软件设计&#xff0c;功耗小&#xff0c;稳定性高&#xff0c;实现了更好的底层封装…

【C++】C++入门1.0

鼠鼠最近在学C&#xff0c;那么好&#xff0c;俺来做笔记了&#xff01; 目录 1.C关键字(C98) 2.命名空间 2.1.命名空间定义 2.2.命名空间的使用 3.C的输入&&输出 4.缺省参数 4.1缺省参数概念 4.2.缺省参数的分类 5.函数重载 5.1.函数重载概念 5.2.C支持函数…