当前位置: 首页 > news >正文

C++之vector类的代码及其逻辑详解 (下)

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.xdnf.cn/news/1251181.html

相关文章:

  • 【Excel】通过Index函数向下拖动单元格并【重复引用/循环引用】数据源
  • 【Linux】调试器gdb/cgdb的使用
  • 推荐一款优质的开源博客与内容管理系统
  • Android PDFBox 的使用指南
  • 【数据结构与算法】刷题篇——环形链表的约瑟夫问题
  • 8.6笔记
  • 93、【OS】【Nuttx】【构建】cmake menuconfig 目标
  • vxe-table表格编辑单元格,进行正则验证,不符合验证,清空单元格数据。
  • 【“连亏十年” 川机器人,启动科创板IPO辅导】
  • 短剧小程序系统开发:技术驱动下的内容创新之路
  • 后端服务oom
  • [linux] Linux系统中断机制详解及用户空间中断使用方法
  • Java技术栈/面试题合集(19)-架构设计篇
  • Android—服务+通知=>前台服务
  • 简单spring boot项目,之前练习的,现在好像没有达到效果
  • 攻防世界WEB(新手模式)20-unseping
  • Android14的QS面板的加载解析
  • Tesseract + Poppler 实现图片型 PDF 转文字
  • jmm 指令重排 缓存可见性 Volatile 内存屏障
  • Perforce P4 Plan - DevOps实时规划工具
  • Python day36
  • 基于单片机智能浇花/智能灌溉/智慧农业/智能大棚
  • 双馈和永磁风机构网型跟网型联合一次调频并入同步机电网,参与系统一次调频,虚拟惯量下垂,虚拟同步机VSG控制matlab/simulink
  • 【软考系统架构设计师备考笔记5】 - 专业英语
  • 【关于Java的泛型(基础)】
  • 《动手学深度学习》读书笔记—9.3深度循环神经网络
  • 阿里云 Flink
  • 第七章课后综合练习
  • SpringBoot 3.x整合Elasticsearch:从零搭建高性能搜索服务
  • 【网络基础】计算机网络发展背景及传输数据过程介绍