【C++精华铺】11.STL vector模拟实现

1.序言

        STL(Standard Template Library)是C++的标准库之一,提供了一系列的模板类和函数,用于实现常用的数据结构和算法。其中,STL的vector是一个动态数组,可以根据需要自动调整大小。

        vector可以存储任意类型的对象,并且可以在尾部插入和删除元素,还可以随机访问和修改任意位置的元素。它的实现使用了动态内存分配,因此在插入和删除元素时,可能会触发内存重新分配和数据拷贝,导致效率降低。

        vector提供了一系列的成员函数和操作符,用于操作和访问其中的元素。一些常用的成员函数包括:push_back()用于在尾部插入元素,pop_back()用于删除尾部元素,size()用于返回元素个数,empty()用于判断是否为空,clear()用于清空元素,等等。

        除了基本的操作函数之外,vector还提供了一些高级的操作,例如使用迭代器(iterator)遍历元素、使用算法函数对元素进行排序、使用resize()改变容器大小、使用reserve()预留容器空间等。

        总之,STL的vector是一个非常有用的数据结构,可以方便地实现动态数组,并且提供了丰富的操作函数和算法,方便程序员进行操作和处理。

2.vector的整体框架

template<class T>
class Vector
{
public://迭代器类型typedef T* iterator;typedef const T* const_iterator;//...private:iterator _start;//数据存储首地址iterator _finish;//有效数据尾部地址下一个地址。iterator _end_of_storage;//容量尾地址下一个地址
};

3.构造与析构


vector()
{} //因为我们给属性添加了缺省值,这里自动使用缺省值初始化~vector()
{delete[] _start; //使用delete[]是因为vector也用于自定义类型,自动调用析构_start = _finish = _end_of_storage = nullptr;
}

4.size() 和 capacity()

        size() 返回元素个数,capacity() 返回容量。

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

5.reserve() 和 resize()

        reserve() 在容量不足时会进行扩容,需要注重的便是深浅拷贝。resize() 当n小于size()时就会删除超出n位置的元素,如果n大于size(),大于size()的部分会进行初始化。如下:

void reserve(size_t n)
{if (n > capacity()){T* tmp = new T[n];if (_start){for (size_t i = 0; i < size(); i++){tmp[i] = _start[i];         //运算符重载深拷贝}delete[] _start;}_finish = tmp + size();_end_of_storage = tmp + n;_start = tmp;}
}
void resize(size_t n, const T& val = T())
{if (n < size()){_finish = _start + n;}else{if (n > capacity()){reserve(n);}while(_finish != _start + n){*(_finish) = val;_finish++;}}
}

6.push_back() 和 pop_back()

        过于简单没什么好说的,注意检查容量。

void push_back(const T& val)
{if (_end_of_storage == _finish)  {reserve(capacity == 0 ? 4 : capacity() * 2);}*(_finish) = val;_finish++;
}bool empty()const
{return size() == 0;
}
void pop_back()
{assert(!empty());_finish--;
}

7.其他构造

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();_end_of_storage = _start + v.capacity();}
vector(size_t n, const T& val = T())
{_start = new T[n];for (size_t i = 0; i < n; i++){push_back(val);}
}
vector(int n, const T& val = T())  //防止优先匹配模板
{_start = new T[n];for (size_t i = 0; i < n; i++){push_back(val);}
}
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);first++;}
}

8.insert() 和 erase()

        insert() 在插入时可能进行扩容,扩容后迭代器失效,需要更新pos,erase() 使用时比如删除最后一个元素,导致pos处于无效位置也会导致pos失效。

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

9.operator[]

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

10.赋值重载

vector<T>& operator=(const vector<T>& v)
{T* tmp = new T[v.capacity];for (size_t i = 1; i < v.size(); i++){tmp[i] = v._start[i];}if (_start){delete[] _start;}_start = tmp;_finish = _start + v.size();_end_of_storage = _start + v.capacity();return *this;
}

11.迭代器

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

12.整体代码

#include<iostream>
#include<assert.h>
using namespace std;
namespace zy
{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;}T& operator[](size_t pos){assert(pos < size() && pos >= 0);return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size() && pos >= 0);return _start[pos];}vector(){}~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}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();_end_of_storage = _start + v.capacity();}vector(size_t n, const T& val = T()){_start = new T[n];for (size_t i = 0; i < n; i++){push_back(val);}}vector(int n, const T& val = T())  //防止优先匹配模板{_start = new T[n];for (size_t i = 0; i < n; i++){push_back(val);}}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);first++;}}size_t size() const{return _finish - _start;}size_t capacity() const{return _end_of_storage - _start;}void reserve(size_t n){if (n > capacity()){T* tmp = new T[n];if (_start){for (size_t i = 0; i < size(); i++){tmp[i] = _start[i];}delete[] _start;}_finish = tmp + size();_end_of_storage = tmp + n;_start = tmp;}}void resize(size_t n, const T& val = T()){if (n < size()){_finish = _start + n;}else{if (n > capacity()){reserve(n);}while(_finish != _start + n){*(_finish) = val;_finish++;}}}void push_back(const T& val){if (_end_of_storage == _finish)  {reserve(capacity == 0 ? 4 : capacity() * 2);}*(_finish) = val;_finish++;}bool empty()const{return size() == 0;}void pop_back(){assert(!empty());_finish--;}iterator insert(iterator pos,const T& val){assert(pos >= _start && pos <= _finish);if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator end = _finish;while (end > pos){*(end) = *(end - 1);}*pos = val;_finish++;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator start = pos;while (start < _finish - 1){*start = *(start + 1);start++;}_finish--;return pos;}vector<T>& operator=(const vector<T>& v){T* tmp = new T[v.capacity];for (size_t i = 1; i < v.size(); i++){tmp[i] = v._start[i];}if (_start){delete[] _start;}_start = tmp;_finish = _start + v.size();_end_of_storage = _start + v.capacity();return *this;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};}

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

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

相关文章

python JSON Lines (JSONL)的保存和读取;jsonl的数据保存和读取,大模型prompt文件保存常用格式

1. JSON Lines (JSONL)文件保存 将一个包含多个字典的列表保存为 JSON Lines (JSONL) 格式的文件&#xff0c;每个字典对应一个 JSONL 文件中的一行。以下是如何实现这一操作的 Python 代码 import json# 定义包含字典的列表 data [{"id": 1, "name": &qu…

数据库系统安全

数据库安全威胁 数据库作为信息系统中的核心组成部分&#xff0c;存储和管理着大量敏感和关键的数据&#xff0c;成为网络攻击者的主要目标之一。以下是常见的数据库安全威胁及其详细描述&#xff1a; 一、常见数据库安全威胁 SQL注入攻击&#xff08;SQL Injection&#xff…

37.深度学习中的梯度下降法及其实现

在深度学习的优化过程中&#xff0c;梯度下降法及其变体是必不可少的工具。通过对梯度下降法的理论学习&#xff0c;我们能够更好地理解深度学习模型的训练过程。本篇文章将介绍梯度下降的基本原理&#xff0c;并通过代码实现展示其具体应用。我们会从二维平面的简单梯度下降开…

使用nodejs进行截图

创建一个空文件夹 初始化项目 npm init -y下载插件 yarn add puppeteer根目录下创建app.js放入以下内容&#xff1a; const puppeteer require(puppeteer);(async () > {// 启动 Puppeteer 并创建一个新浏览器实例// const browser await puppeteer.launch(); // 会在…

大白话讲解AI大模型

大白话讲解大模型 大模型的发展重要大模型发展时间线 大模型的简单原理-训练⼤模型是如何训练并应⽤到场景中的&#xff1f;如果训练私有化模型 模型&#xff1a;model 语料库&#xff1a;用于训练模型的数据 大模型的发展 详细信息来源&#xff1a;DataLearner 2022年11月底…

v-bind指令——03

v-bind 指令详解&#xff1a; 1 、这个指令是干嘛的&#xff1f; 可以让html标签的某个属性的值产生动态的效果 2、v-bind指令的语法格式&#xff1a;<HTML 标签 v-bind : 参数 “表达式”> </HTML> 3、v-bind指令的编译原理&#xff1a; 编译前&#xff1a…

声音的转译者:Transformer模型在语音识别中的革命性应用

声音的转译者&#xff1a;Transformer模型在语音识别中的革命性应用 在人工智能领域&#xff0c;语音到文本转换&#xff08;Speech-to-Text&#xff0c;STT&#xff09;技术正迅速发展&#xff0c;成为连接人类语言与机器理解的桥梁。Transformer模型&#xff0c;以其卓越的处…

关于 RK3588刷镜像升级镜像”没有发现设备“ 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140287339 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

企业资产管理系统带万字文档公司资产管理系统java项目java课程设计java毕业设计

文章目录 企业资产管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 企业资产管理系统 一、项目演示 企业资产管理系统 二、项目介绍 语言&#xff1a;java 数…

javaweb学习day1《HTML篇》--新浪微博(前端页面的创建思路及其HTML、css代码详解)

一、前言 本篇章为javaweb的开端&#xff0c;也是第一篇综合案例&#xff0c;小编也是看着黑马程序员的视频对里面的知识点进行理解&#xff0c;然后自己找一个新浪微博网页看着做的&#xff0c;主要还是因为懒&#xff0c;不想去领黑马程序员的资料了。 小编任务javaweb和ja…

云端日历同步大师:iCloud让工作与生活井井有条

云端日历同步大师&#xff1a;iCloud让工作与生活井井有条 在快节奏的现代生活中&#xff0c;无论是工作还是个人生活&#xff0c;我们都需要一个可靠的日历应用来帮助我们管理日常事务和重要事件。iCloud作为苹果公司提供的云服务&#xff0c;其日历应用&#xff08;Apple Ca…

力扣-dfs

何为深度优先搜索算法&#xff1f; 深度优先搜索算法&#xff0c;即DFS。就是找一个点&#xff0c;往下搜索&#xff0c;搜索到尽头再折回&#xff0c;走下一个路口。 695.岛屿的最大面积 695. 岛屿的最大面积 题目 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相…

helm安装解决无授权问题

在安装kubesphere的时候需要先安装镜像管理工具helm它配合着tiller服务能方面地创建拉取地三镜像库更像一个本地的maven工具&#xff0c;安装helm可以通过脚本的方式担是容易被强&#xff0c;下载二进制的软件包解压得到helm把它移动/user/local/bin目录下&#xff0c;然后查看…

华为HCIP Datacom H12-821 卷33

1.判断题 缺省情况下&#xff0c;华为AR路由器的VRRP运行在抢占模式下 A、对 B、错 正确答案&#xff1a; A 解析&#xff1a; 无 2.判断题 一个Route-Policy下可以有多个节点&#xff0c;不同的节点号用节点号标识&#xff0c;不同节点之间的关系是"或"的关…

禁用华为小米?微软中国免费送iPhone15

微软中国将禁用华为和小米手机&#xff0c;要求员工必须使用iPhone。如果还没有iPhone&#xff0c;公司直接免费送你全新的iPhone 15&#xff01; 、 这几天在微软热度最高的话题就是这个免费发iPhone&#xff0c;很多员工&#xff0c;收到公司的通知。因为&#xff0c;登录公司…

精通Postman响应解析:正则表达式的实战应用

&#x1f9d0; 精通Postman响应解析&#xff1a;正则表达式的实战应用 在API测试和开发的世界中&#xff0c;Postman是一个强大的工具&#xff0c;它不仅可以发送请求、管理环境&#xff0c;还能使用正则表达式来解析响应。正则表达式是一种强大的文本处理工具&#xff0c;能够…

如何指定多块GPU卡进行训练-数据并行

训练代码&#xff1a; train.py import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, Dataset import torch.nn.functional as F# 假设我们有一个简单的文本数据集 class TextDataset(Dataset):def __init__(self, te…

Nginx中文URL请求404

这两天正在搞我的静态网站。方案是&#xff1a;从思源笔记Markdown笔记&#xff0c;用MkOcs build成静态网站&#xff0c;上传到到Nginx服务器。遇到一个问题&#xff1a;URL含有中文会404&#xff0c;全英文URL则正常访问。 ‍ 比如&#xff1a; ​​ ‍ 设置了utf-8 ht…

【Python基础】代码如何打包成exe可执行文件

本文收录于 《一起学Python趣味编程》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、安装PyInstaller三、使用PyInstaller打包四、验证打包是否成功五、总结 一、前言 本文介绍如何…

Linux C语言基础 day8

目录 思维导图&#xff1a; 学习目标&#xff1a; 学习内容&#xff1a; 1. 字符数组 1.1 二维字符数组 1.1.1 格式 1.1.2 初始化 1.1.3 二维字符数组输入输出、求最值、排序 2. 函数 2.1 概念 关于函数的相关概念 2.2 函数的定义及调用 2.2.1 定义函数的格式 2.3…