【C++】vector类的模拟实现(增删查改,拷贝构造,赋值运算,深浅拷贝)

news/2024/10/31 3:27:07/

文章目录

  • 前言
  • 一、 整体
    • 1.命名空间:
    • 2构造函数:
      • 1普通构造
      • 2迭代器构造
      • 3初始化字符构造
      • 4拷贝构造:
    • 3析构函数
  • 二、成员函数实现
    • 1.大小
      • 1当前大小(size())
      • 2总体容量(capacity())
    • 2.返回头尾迭代器
      • 1begin()
      • 2end()
    • 3【】引用重载:
    • 4.内存预留(reserve)
    • 5.调整vector的有效长度(resize)
    • 6.尾插(push_back)
    • 7.在pos插入(insert)
    • 8.删除pos位置(erase)
    • 9.赋值运算符重载
  • 深浅拷贝问题(reserve):


前言

我们模拟vector是用迭代器(start,end,endofstorage)来控制增删查改操作的

在这里插入图片描述

一、 整体

1.命名空间:

namespace simulation {template<class T>//定义模板class vector {public:typedef T* iterator;typedef const T* const_iterator;//private:iterator _start;iterator _finish;iterator _endofstorage;};}

2构造函数:

1普通构造

vector():_start(nullptr),_finish(nullptr),_endofstorage(nullptr){}

2迭代器构造

template<class InputIterator>//【first,last)左闭右开区间vector(InputIterator first, InputIterator last) {while (first != last) {push_back(*first);first++;}}

3初始化字符构造

vector(size_t n, const T& val = T()) {
//const T& val = T()调用T的默认构造的缺省参数resize(n, val);}

4拷贝构造:

vector(const vector<T>& v) {_start = new T[v.capacity()];size_t sz = v.size();//提前记录下sizefor (size_t i = 0; i < sz; i++) {_start[i] = v._start[i];//实行深拷贝}_finish = _start + sz;_endofstorage = _start + v.capacity();}

3析构函数

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

二、成员函数实现

1.大小

1当前大小(size())

//我本身是一个const对象,不可变,所以就需要调用一个const函数,
//但我要是一个非const对象,那么调用非const或者const函数是都都可以的
//这 成员函数加个const,这样const和非const对象都就可以调用了size_t size()const    {return _finish - _start;}

2总体容量(capacity())

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

2.返回头尾迭代器

1begin()

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

2end()

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

3【】引用重载:

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

4.内存预留(reserve)

	void reserve(size_t n) {if (n > capacity()) {T* tmp = new T[n];size_t sz = size();//提前存下size,因为后面start会变动if (_start) {for (size_t i = 0; i < sz; i++) {tmp[i] = _start[i];}
//这里拷贝原来的数据不用memcpy是因为memcpy是浅拷贝我们vector要的是深拷贝
//所以用for循环调用赋值运算符重载,实现对象的深拷贝delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}

5.调整vector的有效长度(resize)

void resize(size_t n, const T& val = T()) {//将前n个数据初始化为val//从当前已有数据后面开始if (n < size()) {_finish = _start + n;}else {reserve(n);while (_finish != _start+n) {*_finish = val;_finish++;}}}

6.尾插(push_back)

void push_back(const T& x) {if (_finish == _endofstorage) {//判断是否需要扩容size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}*_finish = x;_finish++;//或者insert(--end());}

7.在pos插入(insert)

iterator insert(iterator pos, const T& x) {assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage) {size_t len = pos - _start;//算出pos的相对位置size_t newcapacity = capacity() == 0 ? 4 : capacity()  reserve(newcapacity);pos = _start + len;}iterator end = _finish - 1;while (end >= pos) {*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}

8.删除pos位置(erase)

iterator erase(iterator pos) {assert(pos >= _start && pos < _finish);iterator it = pos + 1;//将pos后面的数据朝前覆盖while (it != _finish) {*(it - 1) = *it;++it;}_finish--;return pos;}

9.赋值运算符重载

void swap(vector<T>& v) {std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector& operator=(vector<T>  v) {swap(v);//创建一个临时对象,临时对象为v的拷贝//交换this与v的数据,出了作用域以后//this获得新的数据,临时对象v出作用域销毁return *this;}

深浅拷贝问题(reserve):

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/991374.html

相关文章

解决kite在jupyter lab中显示not running问题

1、问题描述 在anaconda中启动jupyter lab前&#xff0c;安装了jupyterlab-kite。重启jupyter lab&#xff0c;不可以正常使用kite&#xff0c;显示not running。 尝试过重装jupyterlab、jupyterlab-kite等各种方式&#xff0c;但都不管用。经过多次试验与网上查找了诸多文献…

msvcp120.dll丢失的解决方法?哪种解决方法比较推荐?

msvcp120.dll是Microsoft Visual C Redistributable软件包的一部分。它是用于支持运行使用Microsoft Visual C编写的应用程序的动态链接库文件。msvcp120.dll提供了许多C标准库函数和组件&#xff0c;包括输入/输出、字符串处理、数学运算、内存管理等功能。 当您运行某个依赖于…

暑假刷题第18天--7/30

165. 小猫爬山 - AcWing题库(dfs) #include<iostream> #include<string> #include<bitset> #include<cstring> #include<algorithm> using namespace std; const int N18; bool vis[N]; int a[N],n,ans,sum[N],k; bool cmp(int x,int y){retur…

数电基础知识学习笔记

文章目录&#xff1a; 一&#xff1a;逻辑门 1.逻辑门电路的分类 1.1 按逻辑&#xff08;逻辑门&#xff09; 1.1.1 逻辑定义 1.1.2 常见数字电路相关符号 1.1.3 电路图表示 1.1.4 逻辑门电路图像符号 1.2 按电路结构 1.3 按功能特点 2.高低电平的含义 3.常见的门…

在CSDN学Golang云原生(监控解决方案Prometheus)

一&#xff0c;记录规则配置 在golang云原生中&#xff0c;通常使用日志库记录应用程序的日志。其中比较常见的有logrus、zap等日志库。这些库一般支持自定义的输出格式和级别&#xff0c;可以根据需要进行配置。 对于云原生应用程序&#xff0c;我们通常会采用容器化技术将其…

【微服务】springboot整合mongodb使用详解

目录 一、mongodb简介 1.1 什么是mongodb 1.2 mongodb特点 二、mongodb中的核心术语 2.1 mogodb与数据库对比 2.2 mongodb中的核心概念 2.3 与关系数据库的差异 2.3.1 半结构化 2.3.2 支持多级嵌套 2.3.3 关系弱化 三、mongodb 技术优势和应用场景 3.1 mongodb 技术…

SOLIDWORKS软件的优势分析 硕迪科技

在现代的机械设计领域&#xff0c;SOLIDWORKS是一款备受青睐三维设计软件&#xff0c;它具备强大的建模和设计功能&#xff0c;在全球范围内广泛应用于机械设计和工程领域&#xff0c;为用户提供了全面的工程解决方案。本文就SOLIDWORKS的优势进行详细分析。 1、易于学习和使用…

【计算机网络】10、ethtool

文章目录 一、ethtool1.1 常见操作1.1.1 展示设备属性1.1.2 改变网卡属性1.1.2.1 Auto-negotiation1.1.2.2 Speed 1.1.3 展示网卡驱动设置1.1.4 只展示 Auto-negotiation, RX and TX1.1.5 展示统计1.1.7 排除网络故障1.1.8 通过网口的 LED 区分网卡1.1.9 持久化配置&#xff08…