C++的STL简介(三)
目录
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.位置意义变了
相关文章:

C++的STL简介(三)
目录 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&…...

BERT模型
BERT模型是由谷歌团队于2019年提出的 Encoder-only 的 语言模型,发表于NLP顶会ACL上。原文题目为:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》链接 在前大模型时代,BERT模型可以算是一个参数量比…...
举例说明计算机视觉(CV)技术的优势和挑战
计算机视觉(CV)技术是通过计算机模拟和处理图像与视频数据来模拟人类视觉的能力。它可以带来许多优势,也面临一些挑战。 优势: 自动化:CV技术可以自动处理大量的图像和视频数据,从而提高工作效率和准确性。…...

Animate软件基础:关于补间动画中的图层
Animate 文档中的每一个场景都可以包含任意数量的时间轴图层。使用图层和图层文件夹可组织动画序列的内容和分隔动画对象。在图层和文件夹中组织它们可防止它们在重叠时相互擦除、连接或分段。若要创建一次包含多个元件或文本字段的补间移动的动画,请将每个对象放置…...

mac|安装hashcat(压缩包密码p解)
一、安装Macports(如果有brew就不用这一步) 根据官网文档:The MacPorts Project -- Download & Installation,安装步骤如下 1、下载MacPorts,这里我用的是tar.gz ,可以通过keka(keka安装在…...

【保姆级系列:锐捷模拟器的下载安装使用全套教程】
保姆级系列:锐捷模拟器的下载安装使用全套教程 1.介绍2.下载3.安装4.实践教程5.验证 1.介绍 锐捷目前可以通过EVE-NG来模拟自己家的路由器,交换机,防火墙。实现方式是把自己家的镜像导入到EVE-ng里面来运行。下面主要就是介绍如何下载镜像和…...

virtualbox7安装centos7.9配置静态ip
1.背景 我大概在一年之前安装virtualbox7centos7.9的环境,但看视频说用vagrant启动的窗口可以不用第三方工具(比如xshell、secure等)连接centos7.9,于是尝鲜试了下还可以,导致系统文件格式是vmdk了(网上有vmdk转vdi的方法…...

结构型设计模式:桥接/组合/装饰/外观/享元
结构型设计模式:适配器/代理 (qq.com)...

vLLM初识(一)
vLLM初识(一) 前言 在LLM推理优化——KV Cache篇(百倍提速)中,我们已经介绍了KV Cache技术的原理,从中我们可以知道,KV Cache本质是空间换时间的技术,对于大型模型和长序列…...

【Apache Doris】周FAQ集锦:第 18 期
【Apache Doris】周FAQ集锦:第 18 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户…...

docker部署可执行的jar
1.将项目打包,上传到服务器的指定目录 2.在该目录下创建Dockerfile文件 3.Dockerfile写入如下指令 # 基于哪个镜像 FROM java:8 # 拷贝文件到容器,也可以直接写成ADD xxxxx.jar /app.jar ADD springboot-file-0.0.1.jar file.jar RUN bash -c touch /…...

OpenCV||超详细的图像处理模块
一、颜色变换cvtColor dst cv2.cvtColor(src, code[, dstCn[, dst]]) src: 输入图像,即要进行颜色空间转换的原始图像。code: 转换代码,指定要执行的颜色空间转换类型。这是一个必需的参数,决定了源颜色空间到目标颜色空间的转换方式。dst…...
java面向对象期末总结
子类父类方法执行顺序?多态中和子类打印不一样; 子类在实现父类方法的时候没有用super关键字进行调用也会先执行父类的构造方法吗? 是的,当子类实例化时,先执行父类的构造方法,再执行子类的构造方法。即使在…...

文件搜索 36
删除文件 文件搜索 package File;import java.io.File;public class file3 {public static void main(String[] args) {search(new File("D :/"), "qq");}/*** 去目录搜索文件* param dir 目录* param filename 要搜索的文件名称*/public static void sear…...

IO多路转接
文章目录 五种IO模型fcntl多路转接selectpollepollepoll的工作模式 五种IO模型 阻塞IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式.阻塞IO是最常见的IO模型。非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULD…...

基于深度学习的面部表情分类识别系统
:温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 面部表情识别是计算机视觉领域的一个重要研究方向, 它在人机交互、心理健康评估、安全监控等领域具有广泛的应用。近年来,随着深度学习技术的快速发展…...

日志远程同步实验
目录 一.实验环境 二.实验配置 1.node1发送方配置 (1)node1写udp协议 (2)重启服务并清空日志 2.node2接收方配置 (1)node2打开接受日志的插件,指定插件用的端口 (2ÿ…...

数据结构之《二叉树》(中)
在数据结构之《二叉树》(上)中学习了树的相关概念,还了解的树中的二叉树的顺序结构和链式结构,在本篇中我们将重点学习二叉树中的堆的相关概念与性质,同时试着实现堆中的相关方法,一起加油吧! 1.实现顺序结构二叉树 在…...

php json_encode 参数 JSON_PRETTY_PRINT
https://andi.cn/page/621642.html...

【UE 网络】Gameplay框架在DS架构中的扮演的角色
目录 0 引言1 核心内容1.1 Gameplay各部分创建的流程1.2 Gameplay框架在DS和客户端的存在情况1.3 数据是独立存在于DS和客户端的 2 Gameplay框架各自负责的功能2.1 GameMode2.2 GameState2.3 PlayerController2.4 PlayerState2.5 Pawn2.6 AIController2.7 Actor2.8 HUD2.9 UI &…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...