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

vector各种接口的模拟实现

写在前面:

        其实相比string,vector的接口就要简单许多而且更加规范清晰,但是这里也有我们需要注意的问题,一个是浅拷贝的问题,另一个就是迭代器失效

        首先是浅拷贝,这里最容易给自己挖坑的就是在reserve()函数的时候,直接用memcpy()去一个字节一个字节的拷贝,一但调用时使用的是自定义类型,就会因为浅拷贝崩溃(例如vector<string>);其次是迭代器失效,一个是insert,一个是erase,insert之后,除非更新,应当认为迭代器已经失效,比如vs编译器会直接报错,再就是erase,也会出现相同的问题,不过不同点是,insert不一定会迭代器失效,但是erase在不同容器中几乎都会失效

目录

一、基本框架

二、各种构造函数与析构函数

三、增删查改与扩容


一、基本框架

namespace wjl
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;int capacity = _finish - _start;}
}

二、各种构造函数与析构函数

 //vector()//{//这里什么都不需要写,因为编译器一定会走初始化列表//而下面声明的地方我们又给了缺省值,所以已经完成了初始化列表的初始化//}//C++11 强制生成默认构造vector() = default;//只要写了任意的构造,就不会在生成拷贝构造vector(const vector<T>& v){reserve(v.size());for (auto& e : v){push_back(e);}}//输入一个数的和他的个数,将整个vector都用这个数填充
vector(int n, const T& val = T())
{reserve(n);while (n--){push_back(val);}
}~vector()
{if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}
}

三、增删查改与扩容

void clear()
{_finish = _start; 
}vector<T>& operator= (const vector<T>& v)
{clear();if (this != &v){reserve(v.size());for (auto& 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;
}*/iterator begin()
{return _start;
}iterator end()
{return _finish;
}const_iterator begin() const
{return _start;
}const_iterator end() const//意味着传过来的是const对象
{return _finish;
}//这里就是将size变为n,并将变动的空间变为给定的值
void resize(size_t n, T val = T())
{if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;_finish++;}}
}int size()const
{return _finish - _start;
}int capacity()const
{return _end_of_storage - _start;
}//这里是第一个要注意的点
void reserve(size_t n)
{if (n > capacity()){//其实这里就是要注意size的更新问题int old_size = size();T* tmp = new T[n];//memcpy(tmp, _start, size() * sizeof(T));for (int i = 0; i < size(); i++){//这里调用的是string的赋值,完成了深拷贝//内置类型不要紧,但是一但用了自定义类型就会因为浅拷贝导致程序崩溃tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = _start + old_size;_end_of_storage = tmp + n;}
}void push_back(const T& x)
{if (_finish != _end_of_storage){*_finish = x;_finish++;}else{reserve(capacity() == 0 ? 4 : capacity() * 2);*_finish = x;_finish++;}
}T& operator[](int i)
{assert(i < size());return _start[i];
}const T& operator[](int i) const 
{assert(i < size());return _start[i];
}bool empty()const
{return _start == _finish;
}void pop_back()
{assert(!empty());--_finish;
}iterator& erase(iterator pos)
{//进行这样的erase操作之后,vs也会认为pos已经失效assert(pos >= _start);assert(pos <= _finish);iterator it = pos + 1;while (it < end()){*(it - 1) = *(it);it++;}_finish--;return pos;
}void insert(iterator pos, const T& x)
{assert(pos >= _start);assert(pos <= _finish);//迭代器失效——基本上所有容器都会有erase迭代器失效的问题,但是insert不一定// 1、类似野指针 —— 在扩容之后// 2、位置意义已经变了//但是vs编译器进行了强制检查,insert之后访问会直接报错if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;end--;}*pos = x;_finish++;
}

http://www.lryc.cn/news/587071.html

相关文章:

  • python 虚拟环境 Anaconda Miniconda
  • 音视频学习(三十八):像素与位深
  • Linux | 数据库操作基础
  • 【ROS2】自定义消息接口的创建和使用
  • # 通过wifi共享打印机只有手动翻页正反打印没有自动翻页正反打印,而通过网线连接的主机电脑可以自动翻页正反打印
  • 信息收集(外围打点)
  • 在上海开发小程序,怎么做出“高级感”?
  • sql:sql在office中的应用有哪些?
  • 机器学习sklearn入门:使用KNN模型分类鸢尾花和简单调参
  • Matplotlib(一)- 数据可视化与Matplotlib
  • 前端性能优化利器:懒加载技术原理与最佳实践
  • ADRC自抗扰控制—深度解析与实战指南2
  • 适配器模式:兼容不兼容接口
  • 《[系统底层攻坚] 张冬〈大话存储终极版〉精读计划启动——存储架构原理深度拆解之旅》-系统性学习笔记(适合小白与IT工作人员)
  • Redis数据类型之zset
  • 补:《每日AI-人工智能-编程日报》--2025年7月12日
  • Vue单文件组件与脚手架工程化开发
  • 小白学Python,操作文件和文件夹
  • 【王树森推荐系统】重排04:DPP 多样性算法(上)
  • leetGPU解题笔记(2)
  • CSAPP_第一章:计算机系统漫游读书笔记
  • 从文本中 “提取” 商业洞察“DatawhaleAI夏令营”
  • 通信子网 V
  • Java 内部类详解:从基础到实战,掌握嵌套类、匿名类与局部类的使用技巧
  • 一天速通TypeScript入门基础知识
  • Java反射机制深度解析
  • VsCode的LivePreview插件应用
  • 20250713-day14
  • UNet改进(22):融合CNN与Transformer的医学图像分割新架构
  • 板凳-------Mysql cookbook学习 (十一--------9)