C++的STL简介(三)

news2025/1/19 19:43:22

目录

1.vector的模拟实现

 1.1begin()

 1.2end()

 1.3打印信息

 1.4 reserve()

 1.5 size()

 1.6 capacity()

 1.7 push_back()

 1.8[ ]

 1.9 pop_back()

 1.10 insert()

 1.11拷贝构造

1.12析构函数

 1.13 =

 1.14chear

 1.15区间构造

 1.16默认构造

 2.完整代码

 3.迭代器失效问题

1.类似野指针

​编辑2.位置意义变了


C++ 中的 vector 是一种序列容器,它允许你在运行时动态地插入和删除元素。

vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。

与 C++ 数组相比,vector 具有更多的灵活性和功能,使其成为 C++ 中常用的数据结构之一。

vector 是 C++ 标准模板库(STL)的一部分,提供了灵活的接口和高效的操作。

基本特性:

  • 动态大小vector 的大小可以根据需要自动增长和缩小。
  • 连续存储vector 中的元素在内存中是连续存储的,这使得访问元素非常快速。
  • 可迭代vector 可以被迭代,你可以使用循环(如 for 循环)来访问它的元素。
  • 元素类型vector 可以存储任何类型的元素,包括内置类型、对象、指针等。

使用场景:

  • 当你需要一个可以动态增长和缩小的数组时。
  • 当你需要频繁地在序列的末尾添加或移除元素时。
  • 当你需要一个可以高效随机访问元素的容器时。

1.vector的模拟实现

基本框架

namespace V
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef  const T* const_iterator;
		
		iterator _start=nullptr;
		//开始
		iterator _finish=nullptr;
		//存数据
		iterator _end_of_storage=nullptr;
		//结束

	};

 1.1begin()

开始位置的迭代器


		iterator begin()
		{
			return _start;
		}
		
		const_iterator begin() const
		{
			return _start;
		}
		

 1.2end()

结束位置的迭代器


		iterator end()
		{
			return _finish;
		}
		const_iterator end() const
		{
			return _finish;
		}
		

 1.3打印信息

template<class T>
	 void print_vector(const  vector<T>& v)
		{
		//没有实例化的类模板里面取东西,编译器不能区分这里const_iterator是类型还是静态成员变量
		typename vector<T>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
			cout << endl;
		}
		}

	 typename void print_vector(  vector<T>& v)
	{
		vector<T>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
			cout << endl;
		}
	}
		

 1.4 reserve()

扩容

	void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old_size = size();
				T* tmp = new T[n];
				memcpy(tmp, _start, size() * sizeof(T));
				delete[] _start;
				_finish =  tmp + old_size();
				_start = tmp;
				_end_of_storage = _start + n;
			}
		}
		

 1.5 size()

内容个数

size_t size()
		{
			return _finish - _start;
		}
		

 1.6 capacity()

容量

size_t capacity()
		{
			return _end_of_storage - _start;
		}
		

 1.7 push_back()

尾插

	void push_back(const T& x)
		{
			if (_finish == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

				*_finish = x;
				++_finish;
			}
			

 1.8[ ]

下标访问

T& operator[](size_t i)
			{
				assert(i < size());
				return _start[i];
		}
		const T& operator[](size_t i) const
			{
				assert(i < size());
				return _start[i];
			}
		bool empty()
		{
			return _start == _finish;
		}

			
		

 1.9 pop_back()

尾删

void pop_back()
		{
			assert(empty());
			--_finish;

		}
	

 1.10 insert()

插入

	void insert(iterator pos, const T& x)
		{
			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator end = _finsh - 1;
			while (end>=pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;
		}

 1.11拷贝构造

vector(const vector<T>& v)
{
	reserve(v.size());
	for (auto& e : v)
	{
		push_back(e);
	}
}

1.12析构函数

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

 1.13 =

vector<T>& operator=(const vector<T>& v)
{
	if (this != &v)
	{
		chear();
        reserve(v.size());
		for(ayto& e:v)
		{
			push_back(e);
		}
	}
	return *this;
}

 现代写法

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

 1.14chear

清除数据

	void clear()
	{
		_finish = _start;
	}

 1.15区间构造

	//类模板的成员函数还可以继续是函数模板
	//区间构造
	template <class InputIterator>
	vector(InputIterator first, InputIterator last)
	{
		while (first != last)
		{
			push_back(*first);
			++firsh;
		}
	}

 

 1.16默认构造

n个T()初始化

	vector(size_t n ,const T& val=T())
	{
		reserve(n);
		for (size_t i = 0; i < n; i++)
		{
			push_back(val);
		}
	}

 2.完整代码

#include<iostream>
#include<assert.h>
#define _CRT_SECURE_NO_WARNINGS 1
using namespace std;
namespace V
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef  const T* const_iterator;
		vector()
		{}
		vector(const vector<T>& v)
		{
			reserve(v.size());
			for (auto& e : v)
			{
				push_back(e);
			}
		}
		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _end_of_storage = nullptr;
		}
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin() const
		{
			return _start;
		}
		const_iterator end() const
		{
			return _finish;
		}
		template<class T>
	 void print_vector(const  vector<T>& v)
		{
		//没有实例化的类模板里面取东西,编译器不能区分这里const_iterator是类型还是静态成员变量
		typename vector<T>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
			cout << endl;
		}
		}

	 typename void print_vector(  vector<T>& v)
	{
		vector<T>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
			cout << endl;
		}
	}
			void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old_size = size();
				T* tmp = new T[n];
				memcpy(tmp, _start, size() * sizeof(T));
				delete[] _start;
				_finish =  tmp + old_size();
				_start = tmp;
				_end_of_storage = _start + n;
			}
		}
		size_t size()
		{
			return _finish - _start;
		}
		size_t capacity()
		{
			return _end_of_storage - _start;
		}
			void push_back(const T& x)
		{
			if (_finish == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

				*_finish = x;
				++_finish;
			}
			T& operator[](size_t i)
			{
				assert(i < size());
				return _start[i];
		}
		const T& operator[](size_t i) const
			{
				assert(i < size());
				return _start[i];
			}
		void clear()
		{
			_finish = _start;
		}
/*		vector<T>& operator=(const vector<T>& v)
		{
			if (this != &v)
			{
				chear();
				reserve(v.size());
				for(ayto& e:v)
				{
					push_back(e);
				}
			}
			return *this;
		}
*/
		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}
		//类模板的成员函数还可以继续是函数模板
		//区间构造
		template <class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				++firsh;
			}
		}
		vector(size_t n ,const T& val=T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}
		
		bool empty()
		{
			return _start == _finish;
		}

			
		void pop_back()
		{
			assert(empty());
			--_finish;

		}
		void insert(iterator pos, const T& x)
		{
			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator end = _finish - 1;
			while (end>=pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;
		}

	private:
		iterator _start=nullptr;
		//开始
		iterator _finish=nullptr;
		//存数据
		iterator _end_of_storage=nullptr;
		//结束

	};
	
	
	
	
}

 3.迭代器失效问题

1.类似野指针

最开始_finish=_start=_end_of_storage=0;经过扩容,_start已经不为nullptr了,用一个nullptr减一个地址,用扩容前的地址减去扩容后的地址,_finish访问后地址就类似野指针,本意是想_finish存储最后一个数据的地址,可是实际差强人意这段代码肯定有问题但是编译器不报错

 修正一下,用old_size存储相对位置在进行计算就更合理

	void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old_size = size();
				T* tmp = new T[n];
				memcpy(tmp, _start, size() * sizeof(T));
				delete[] _start;
				_finish =  tmp + old_size();
				_start = tmp;
				_end_of_storage = _start + n;
			}
		}

1.2

 扩容后,pos还指向旧空间,while循环end-pos次,迭代器失效

 任然是用相对位置

void insert(iterator pos, const T& x)
		{
			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator end = _finsh - 1;
			while (end>=pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;
		}

  pos被释放后失效了虽然后面修正了形参的改变不影响实参实参仍然指向旧空间,访问旧空间,迭代器失效

2.位置意义变了

 

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

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

相关文章

扑克游戏(函数规范化,拆分事件)

前言&#xff1a; 题目链接 进入链接后&#xff0c;点击实践项目&#xff0c;以下两道题分别为6.8.15和6.8.16, 这两道题算不上难&#xff0c;特别是第二道在之前某个比赛中遇到过一次&#xff0c;当时没做出来&#xff0c;想着去找的&#xff0c;没找着&#xff0c;现在又看…

Midjourney小技巧-提升出图质量的常用公式

一个公式让你的Midjourney生成更具韵味的人像身影图 step1-测试&#xff1a;输入提示词 - 一个面容精致的亚洲女性 - An Asian woman with a delicate face 生成的图片还是挺唯美的&#xff0c;就是过于单调&#xff0c;稀疏平常 step2-使用公式&#xff1a; 谁谁&#xff0…

Windows调大虚拟内存来代替升级物理运行内存(RAM)真的有用吗?

前言 前段时间有个粉丝突发奇想说&#xff1a;电脑运行内存不足&#xff0c;调大虚拟内存来代替升级物理运行内存&#xff08;内存条&#xff09;不就可以了&#xff1f;剩下的大几百块钱吃香的喝辣的不好吗&#xff1f; 嗯。。。直到2024年的今天&#xff0c;估计还有很多小…

微信VX多开 免扫码 登录 互斥体 可视化 Exui v1.1 易语言源码附成品软件

UI设计&#xff1a; 1. EXUI界面库20240204 调用的模块&#xff1a; 1. wow64_hook_3.02.ec&#xff08;压缩包内含&#xff09; 2. 精易模块[v11.1.0].ec&#xff08;自行下载&#xff09; 更新日志&#xff1a; v1.1 2024年7月25日13:28:43 { 1. 有人反馈 设置了V…

“论数据湖技术及其应用”写作框架,软考高级论文系统架构设计师论文

论文真题 近年来&#xff0c;随着移动互联网、物联网、工业互联网等技术的不断发展&#xff0c;企业级应用面临的数据规模不断增大&#xff0c;数据类型异常复杂。针对这一问题&#xff0c;业界提出“数据湖&#xff08;Data Lake)”这一新型的企业数据管理技术。数据湖是一个…

YOLOv1-v5总结

文章目录 1、yolov11.2、预测阶段1.3、后处理阶段1.4、模型训练阶段1.5、损失函数1.6、yolov1网络1.7、为什么使用1*1的卷积&#xff1f; 2、yolov22.1、添加BN层2.2、高分辨力分类器&#xff08;仅仅使用分类而不是目标检测&#xff09;2.3、anchor机制2.4、关于anchor boxes&…

Python 爬虫项目实战(二):爬取微博热搜榜

前言 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;也称为网页蜘蛛&#xff08;Web Spider&#xff09;或网页机器人&#xff08;Web Bot&#xff09;&#xff0c;是一种按照既定规则自动浏览网络并提取信息的程序。爬虫的主要用途包括数据采集、网络索引、内容抓…

iPhone苹果密码解锁工具专业版_不限制电脑

iPhone苹果密码解锁工具专业版_不限制电脑 Aiseesoft iPhone Unlocker&#xff1a;轻松解锁iPhone。功能强大&#xff1a;一键移除4位、6位密码、Touch ID和Face ID。 隐私保护&#xff1a;创建密码&#xff0c;安全无忧。数据提醒&#xff1a;解锁时&#xff0c;注意数据和设…

自制安卓车机软件(含APP)

本软件使用APPinventor2编程软件&#xff0c;耗时5天和3天调试&#xff0c;具有高德导航&#xff0c;视频播放&#xff0c;网易云音乐&#xff0c;酷狗&#xff0c;抖音&#xff0c;&#xff08;需下载车机版软件&#xff09;和自定义添加软件&#xff0c;网页有哔哩哔哩&#…

STM32F103 SPI详解及示例代码1

1 SPI协议详解 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;是美国摩托罗拉公司&#xff08;Motorola&#xff09;最先推出的一种同步串行传输规范&#xff0c;也是一种单片机外设芯片串行扩展接口&#xff0c;是一种高速、全双工…

学习笔记-JWT 保持登录状态

目录 一、解析 token 1. 在 JWT 工具类添加解析 token 的方法 2. 在 Controller 添加获取用户数据的方法 二、获取用户信息 1. 发起 axios 请求用户信息 2. 在路由守卫中调用方法 3. 使用 三、token 时效性 1. 设置 token 过期时间 2. 判断 token 是否过期 3. 在拦截…

Golang是如何实现动态数组功能的?Slice切片原理解析

Hi 亲爱的朋友们&#xff0c;我是 k 哥。今天&#xff0c;咱们聊一聊Golang 切片。 当我们需要使用数组&#xff0c;但是又不能提前定义数组大小时&#xff0c;可以使用golang的动态数组结构&#xff0c;slice切片。在 Go 语言的众多特性里&#xff0c;slice 是我们经常用到的数…

基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 MSER 4.2 HOG特征提取 4.3 SVM 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2017b 3.部分核心程序 &#xff08;完整版代码包含中…

黑马头条vue2.0项目实战(四)——首页—文章列表

目录 1. 头部导航栏 1.1 页面布局 1.2 样式调整中遇到的问题 2. 频道列表 2.1 页面布局 2.2 样式调整 2.3 展示频道列表 3. 文章列表 3.1 思路分析 3.2 使用 List 列表组件 3.3 加载文章列表数据 3.4 下拉刷新 3.5 设置上下padding固定头部和频道列表 3.6 记住列…

48天笔试训练错题——day40

目录 选择题 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 编程题 1. 发邮件 2. 最长上升子序列 选择题 1. DNS 劫持又称域名劫持&#xff0c;是指在劫持的网络范围内拦截域名解析的请求&#xff0c;分析请求的域名&#xff0c;把审查范围以外的请求放行&#xff0c;否则返回…

大数据Flink(一百零七):阿里云Flink的应用场景

文章目录 阿里云Flink的应用场景 一、​​​​​​​背景信息 二、​​​​​​​​​​​​​​部门场景 三、​​​​​​​​​​​​​​技术领域 1、​​​​​​​​​​​​​​实时ETL和数据流 2、​​​​​​​​​​​​​​实时数据分析 3、​​​​​​​事…

8.3总结

1.改进渲染 这个渲染为了美观我做了很久花了好多时间&#xff0c;&#xff0c;&#xff0c; // 加载头像图像InputStream inputStream new ByteArrayInputStream(message.getFileBytes());Image image new Image(inputStream); // 第二个参数表示是否缓存图片&#xff0c;根…

达梦数据库dsc集群动态添加节点

前提条件&#xff1a;在安装好的的dsc集群&#xff1a;达梦数据库dsc集群保姆级部署文档_达梦数据库文档-CSDN博客上动态添加节点 1、环境信息 扩展节点信息&#xff1a; 操作环境&#xff1a;VMware Workstation 16 Pro dmdsc集群 机器ip 主机名 操作系统 资源配置 实…

mac中dyld[5999]: Library not loaded: libssl.3.dylib解决方法

需要重新安装下openssl3.0版本 brew reinstall openssl3.0 安装后执行还是报错&#xff0c;需要找到openssl的安装路径 /opt/homebrew/Cellar/openssl3.0/3.0.14/lib/ 将libssl.3.dylib和libcrypto.3.dylib拷贝到自己的二进制文件同目录下&#xff0c;再执行二进制文件就可…

YUM软件包管理工具:更改YUM源、配置本地YUM仓库

文章目录 YUM软件包管理工具更改YUM源配置过程网络出错&#xff0c;配置网卡 本地YUM仓库配置挂载配置本地yum源 YUM软件包管理工具 YUM&#xff08;Yellowdog Updater, Modified&#xff09;是一个在Linux系统中广泛使用的开源软件包管理工具&#xff0c;尤其常见于Fedora、R…