1. insert()

这个就是在指定位置插入一个元素,首先计算要插入的这个位置和开头之间的距离,接着判断那个_finish 有没有碰到_endofstorage 或者_endofstorage 是不是为0,如果满足条件,那就进行扩容,然后接着重新计算距离,因为我们经过扩容了,所以可能插入的位置会不准,所以要重新计算,接着我们算一个end,这个end就是最后一个元素的位置,然后通过挪动的方式留出pos的空间,接着插入对应元素再++_finish 。

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

2. reserve()

这个函数就是改变vector的capacity,同时并不像resize一样会添加或者减少元素。

首先保存当前元素数量 sz,然后动态分配大小为 n 的新内存 tmp。若原内存_start 非空,则通过循环调用元素的赋值运算符将原数据逐个复制到新内存中(而非直接使用 memcpy,避免浅拷贝问题),随后释放原内存。最后更新_start 指向新内存,_finish 指向原元素末尾的下一个位置,_endofstorage 指向新容量的末尾。若 n 不大于当前容量,则不执行任何操作。

简单来说就是新开一个扩容后数组然后把旧的赋值给他,接着直接把原来的vector的三个指针直接指向新的,从而完成替换实现reserve。

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

3.  resize()

这个函数就是改变vector的大小,如果比原来的size小,那就改变finish的位置。

如果比原来的size大,那就吧finish向后移动,并在每一个添加的位置赋值为val。

PS:这个val之所以要设计成const T& val=T(),是因为我们并不知道这个vector里面是什么类型的,在加上这个resize在stl库里面支持只给一个n,所以我们在这里就这么设计。意思是表用它的默认构造,我们在这里不用担心int这种内置类型,因为C++支持像int a=int(1)这种语法了。

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

4. swap()

这个的话就是交换两个vetcor里面的内容。

原理上来说的话就是通过swap两个vector里面的三个指针来实现。

void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}

5. capacity()

这个的话就是返回vector的capacity,因为_endofstorage和_start是指针而不是实际的大小,所以我们在这里要做减法。

size_t capacity() const
{return (_endofstorage - _start);
}

6. size()

这个的话就是返回vector的size,原因的话和上面一样。

size_t size() const
{return (_finish - _start);
}

7. operator[]

这个的话是运算符重载的[],简单来说就是可以通过下标的方式来对vector里面的内容进行访问。

同时在这里提供了普通版本和const版本。

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

8. print()

这个就是打印,通过迭代器的方式来对vector里面的内容进行打印。

void print()
{for (auto e : *this){std::cout << e << ' ';}cout << endl;
}

 9. 总结

本文围绕C++中的vector容器展开了全面解析,从基础特性到具体接口操作进行了系统梳理。

首先,明确了vector的核心特性及空间结构,让读者对其底层存储有了整体认知;接着,深入讲解了vector类的关键成员与函数,包括私有成员的作用,以及构造函数(默认、拷贝、范围构造)和析构函数在对象创建与销毁时的机制;同时,详细介绍了迭代器相关的begin、end接口,以及erase、pop_back、insert等元素增删操作,reserve、resize、swap等空间与容器管理函数,还有capacity、size的获取方式;此外,还涵盖了重载的方括号运算符(用于便捷访问元素)和print方法(用于元素输出)。

通过这些内容,全面呈现了vector的使用逻辑与核心功能,帮助读者从底层原理到实际操作,完整掌握vector容器的应用。

以下是vector的完整代码:

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace struggle
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){_start = new T[v.capacity()];for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish =_start+v.size();_endofstorage = _start + v.capacity();}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}vector():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}~vector(){delete[] _start;_start = _finish = _endofstorage = 0;}void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (int i = 0; i < sz; i++) {tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}void push_back(const T& x){if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}*_finish = x;++_finish;}size_t capacity() const{return (_endofstorage - _start);}size_t size() const{return (_finish - _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 resize(size_t n, const T& val=T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*(_finish) = val;++_finish;}}}void erase(iterator pos){assert(pos >= _start && pos < _finish);iterator it = pos;while (it + 1 != _finish){*it = *(it + 1);++it;}--_finish;}void pop_back(){assert(_start != _finish);--_finish;}void insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);size_t len = pos - _start;if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}pos = _start + len;iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}/*void print(const vector<int>& v){for(auto e:v){std::cout << e << ' ';}cout << endl;}*/void print(){for (auto e : *this){std::cout << e << ' ';}cout << endl;}private:iterator _start;iterator _finish;iterator _endofstorage;};
}

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

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

相关文章

【自动化测试】Python Selenium 自动化测试元素定位专业教程

1. 引言&#xff1a;元素定位在 Selenium 中的核心地位 元素定位是 Selenium 自动化测试的基础&#xff0c;所有用户交互操作&#xff08;如点击、输入、选择&#xff09;都依赖于准确识别页面元素。Selenium WebDriver 提供了多种定位策略&#xff0c;从简单的 ID 定位到复杂…

通用代码自用

多文件上传public int save(Role role, RequestParam("nfile") MultipartFile nfile, HttpServletRequest request) {System.out.println(nfile.getOriginalFilename());String path request.getSession().getServletContext().getRealPath("/upload");Fi…

生成式AI如何颠覆我们的工作和生活

原问题&#xff1a; ​你觉得生成式AI未来会如何改变普通人的工作和生活&#xff1f;​ 做过一个对比国外和国内工业化产品制造的简单调研&#xff0c;类似一款定制化的台灯或者语音音响&#xff0c;从零到原型实物&#xff0c; 美国至少需要20万美刀&#xff0c;国内成本大概…

K8S、Docker安全漏洞靶场

1 介绍 一个脆弱基础设施自动化构建框架,主要用于快速、自动化搭建从简单到复杂的脆弱云原生靶机环境。 1.1 项目的缘起 在研究漏洞时,我们经常会发现“环境搭建”这一步骤本身就会占用大量的时间,与之相比,真正测试PoC、ExP的时间可能非常短。由于许多官方镜像在国内的…

使用Nginx部署前后端分离项目

使用Nginx部署前后端分离项目&#xff1a;用户中心系统实践指南 部署前的关键准备 在正式部署前&#xff0c;务必确保前后端在生产环境能正常运行&#xff1a; 前端&#xff1a;测试所有API请求路径和生产环境配置后端&#xff1a;验证数据库连接、环境变量和外部服务集成完整流…

当前就业形势下,软件测试工程师职业发展与自我提升的必要性

软件测试行业正处于深刻变革期&#xff0c;2025年的市场已超越400亿美元规模&#xff0c;预计2027年将增长7% 。在这个技术驱动、效率至上的时代&#xff0c;测试工程师若想保持竞争力&#xff0c;必须主动拥抱变革&#xff0c;系统性提升技能。通过深入分析行业现状与人才需求…

java 之 继承

一、继承 1.1 、什么是继承&#xff1f; 继承就是把所有的类的公共部分&#xff08;相同的成员&#xff09;提取出来&#xff0c;放到一个类中继承需要使用 extends 关键字 public class Animal{ public String name&#xff1b; } public class Dog extends Animal{}Dog 是 An…

强化应急通信生命线:遨游三防平板、卫星电话破局极端灾害救援

暴雨倾盆&#xff0c;山洪咆哮&#xff0c;城市陷入内涝。今年进入汛期以来&#xff0c;我国广东、福建、河南、陕西、京津冀等地相继遭遇暴雨、洪涝、山洪等灾害&#xff0c;道路损毁、基站断网、电力中断等次生问题为应急响应带来严峻挑战。如何保障极端场景下的通信畅通&…

【Linux系统】进程间通信:命名管道

1. 匿名管道的限制匿名管道存在以下核心限制&#xff1a;仅限亲缘关系进程&#xff1a;只能用于父子进程等有血缘关系的进程间通信&#xff08;如通过 fork() 创建的子进程&#xff09;。单向通信&#xff1a;数据只能单向流动&#xff08;一端写&#xff0c;另一端读&#xff…

Python Day24 多线程编程:核心机制、同步方法与实践案例

一、线程事件对象&#xff08;threading.Event&#xff09;threading.Event 用于实现线程间的通信&#xff0c;可让一个线程通知其他线程终止任务&#xff0c;核心是通过 “事件触发” 机制协调线程行为。核心方法&#xff1a;创建事件对象&#xff1a;event threading.Event(…

007 前端( JavaScript HTML DOM+Echarts)

一.html dom运用查找html元素的三种方式通过 id 找到 HTML 元素通过标签名找到 HTML 元素通过类名找到 HTML 元素1.通过 id 找到 HTML 元素<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>msf的网页</title> <…

实习文档背诵

实习内容:1.定时任务与数据补全:基于 XXL-JOB 实现分布式定时任务调度&#xff0c;补全近半年历史操作日志数据&#xff0c;有效解决因网络异常导致的数据缺失问题。业务场景&#xff1b;集团的4a日志半年内没有同步&#xff0c;这边需要把日志数据同步到集团上首先先评估每天的…

分布式CAP定理

CAP 定理在一个分布式系统中&#xff0c;以下三个特性不可能同时完全满足&#xff0c;最多只能满足其中两个&#xff1a;C&#xff08;Consistency&#xff0c;一致性&#xff09;&#xff1a;所有节点在同一时间看到的数据是完全一致的&#xff08;即更新操作成功并返回后&…

PHP-Casbin:现代化 PHP 应用的权限管理引擎

在当今复杂的Web应用中&#xff0c;精细化的权限管理是保障系统安全的关键环节。PHP-Casbin 作为Casbin生态的PHP实现&#xff0c;凭借其灵活的模型支持和强大的扩展能力&#xff0c;已成为PHP开发者实现访问控制的首选工具。 超越传统权限模型 PHP-Casbin 基于PERM&#xff…

FastDeploy2.0:环境变量的说明

一、执行# 设置日志目录 export FD_LOG_DIR/workspace/models/log# 指定使用的 GPU 设备 export CUDA_VISIBLE_DEVICES0,1,2,3# 创建日志目录&#xff08;如果不存在&#xff09; mkdir -p "$FD_LOG_DIR"# 定义日志文件路径 LOG_FILE"$FD_LOG_DIR/fastdeploy_se…

C语言:指针(1-2)

5. 指针运算指针的基本运算有三种&#xff0c;分别是&#xff1a;指针-整数指针-指针指针的关系运算5.1 指针运算在上面&#xff0c;我们知道&#xff0c;数组在内存中是连续存放的&#xff0c;只要知道第一个元素的地址&#xff0c;顺藤摸瓜就能找到后面的所有元素。那么&…

【多模态】DPO学习笔记

DPO学习笔记1 原理1.0 名词1.1 preference model1.2 RLHF1.3 从RLHF到DPOA.解的最优形式B. DPO下参数估计C. DPO下梯度更新D. DPO训练的稳定性2 源代码2.1 数据集构成2.2 计算log prob2.3 DPO loss1 原理 1.0 名词 preference model&#xff1a;对人类偏好进行建模&#xff0…

2025最新、UI媲美豆包、DeepSeek等AI大厂的AIGC系统 - IMYAI源码部署教程

IMYAI 系统部署与使用手册 一、系统演示 &#x1f539; 快速体验 前端演示地址&#xff1a;https://super.imyaigc.com后台演示地址&#xff1a;https://super.imyaigc.com/settings &#x1f539; 技术架构 前端&#xff1a;Vite Vue3 NaiveUI TailwindCSS Plyr后端&…

【关于Java的反射】

在 Java 编程中&#xff0c;反射&#xff08;Reflection&#xff09; 是一个非常强大的工具&#xff0c;它允许你在运行时动态地获取类的信息、创建对象、调用方法和访问字段。虽然反射功能强大&#xff0c;但它也有一些局限性和性能开销&#xff0c;因此需要谨慎使用。一、什么…

Gitee推出“移动软件工厂“解决方案 解决嵌入式与涉密场景研发困局

Gitee推出"移动软件工厂"解决方案 破解嵌入式与涉密场景研发困局 随着数字化转型浪潮的推进&#xff0c;软件开发正面临着前所未有的复杂环境挑战。特别是在嵌入式系统、FPGA开发以及涉密信息系统等特殊场景下&#xff0c;研发团队往往需要在高安全要求与有限网络环境…