c++:vector模拟实现

一、vector成员变量

 库里实现用的就是这三个成员变量,咱们实现跟库里一样,

namespace myvector {template<class T>class vector{public://vecttor的迭代器是原生指针typedef T* iterator;typedef const T* const_iterator;	private:iterator _start=nullptr;//数据块的开始--------------_beginiterator _finish=nullptr;//有效数据的尾-------------_enditerator _end_of_storage=nullptr;//存储容量的尾-----_capacity}

 这里把T*重命名为iterator,因为vector的迭代器就是原生指针,所以直接用就行。

二、默认成员函数

1.构造函数

        //我们在成员变量声明处给了缺省值,这里就可以不用初始化了vector(){}//T()是匿名对象,初始化n个valuevector(size_t n, const T& value = T()){resize(n, value);}/** 理论上讲,提供了vector(size_t n, const T& value = T())之后* vector(int n, const T& value = T())就不需要提供了,但是对于:* vector<int> v(10, 5);* 编译器在编译时,认为T已经被实例化为int,而10和5编译器会默认其为int类型* 就不会走vector(size_t n, const T& value = T())这个构造方法,* 最终选择的是:vector(InputIterator first, InputIterator last)* 因为编译器觉得区间构造两个参数类型一致,因此编译器就会将InputIterator实例化为int* 但是10和5根本不是一个区间,编译时就报错了* 故需要增加该构造方法*///初始化 n个valuevector(int n, const T& value = T()){resize(n, value);}// 若使用iterator做迭代器,会导致初始化的迭代器区间[first,last)只能是vector的迭代器// 重新声明迭代器,迭代器区间[first,last)可以是任意容器的迭代器//初始化一段空间template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}

2.拷贝构造和赋值运算符重载

		//拷贝构造vector(const vector<T>&v){_start = new T[v.capacity()];//vector是深拷贝,但是vector空间上存一个开空间的自定义类型数组,例:string的数组//使用memcpy导致string对象的浅拷贝//memcpy(tmp, _start, sizeof(T) * size());for (size_t i = 0; i < v.size(); i++){//假设T是string类型,这里调用string的赋值运算符重载,是深拷贝_start[i]=v._start[i];}_finish = v.size() + _start;_end_of_storage = v.capacity() + _start;}vector<T>& operator=(vector<T> v){swap(v);return *this;}void swap(vector<T>& v){std::swap(v._start, _start);std::swap(v._finish, _finish);std::swap(v._end_of_storage, _end_of_storage);}

这里赋值运算符重载的形参是传值, 会调用拷贝构造出一个临时对象v,(深拷贝),然后用库里的swap把v的参数交换,交换完后待赋值运算符重载结束后会自动析构掉临时对象v。

  1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中
  2.  如果拷贝的是自定义类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝。

 

 结论:如果对象中涉及到资源管理时,千万不能使用memcpy进行对象之间的拷贝,因为memcpy是浅拷贝,否则可能会引起内存泄漏甚至程序崩溃。

3.迭代器

        //vecttor的迭代器是原生指针typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator cbegin()const{return _start;}const_iterator cend()const{return _finish;}

 迭代器这里没什么大问题,直接用就行。

4.析构函数

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

 为空就没有可释放的资源。

、空间增长接口

        size_t capacity()const{return _end_of_storage - _start;}size_t size()const{return _finish - _start;}void reserve(size_t n){//只扩容,不缩容if (n > capacity()){size_t sz = size();T* tmp = new T[n];//如果_start为空,直接把tmp赋值给_start就行,不用释放旧空间if (_start){//vector是深拷贝,但是vector空间上存一个开空间的自定义类型数组,例:        //string的数组//使用memcpy导致string对象的浅拷贝//memcpy(tmp, _start, sizeof(T) * size());for (size_t i=0;i<size();i++){//假设T是string类型,这里调用string的赋值运算符重载,是深拷贝tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = tmp + sz;_end_of_storage = tmp + n;}}void resize(size_t n, const T& value = T()){//三种情况//n<sizeif (n < size()){iterator pos = _start + n;while (pos != _finish){erase(pos);}}//n>容量,要扩容else if (n > size()){//n大于size但小于容量if (n > capacity()){reserve(n);}while (_finish != _start + n){push_back(value);}}}

这里只要注意临界条件就行了。

、增删接口

        void push_back(const T& value){满了,扩容//if (_finish == _end_of_storage)//{//	size_t newcapacity = capacity() < 4 ? 4 : capacity() * 2;//	reserve(newcapacity);//}//*_finish = value;//++_finish;insert(_finish, value);}void pop_back(){erase(_finish-1);}iterator insert(iterator pos, const T& x){assert(pos <= _finish);// 空间不够先进行增容if (_finish == _end_of_storage){//size_t size = size();size_t newCapacity = (0 == capacity()) ? 1 : capacity() * 2;reserve(newCapacity);// 如果发生了增容,需要重置pos,防止迭代器失效pos = _start + size();}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}// 返回删除数据的下一个数据// 方便解决:一边遍历一边删除的迭代器失效问题iterator erase(iterator pos){// 挪动数据进行删除iterator begin = pos + 1;while (begin != _finish) {*(begin - 1) = *begin;++begin;}--_finish;return pos;}

 五、其他

        T& front(){return *_start;}T& back(){return *(_finish - 1);}T& operator[](size_t pos){//判断pos位置合法性assert(pos < size());return *(_start + pos);}const T& operator[](size_t pos)const{//判断pos位置合法性assert(pos < size());return *(_start + pos);}

总结

vector实现只要注意迭代器失效的问题和拷贝不能用memcpy这俩问题。

蟹蟹观看!点赞!关注!收藏!评论!一键三连!

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

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

相关文章

【热门主题】000023 计算机视觉:算法与应用的深度探索

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

国产服务器平台离线部署k8s和kubesphere(含离线部署新方式)

"信创&#xff1a;鲲鹏麒麟&#xff0c;ARM64架构&#xff0c;实现K8s和Kubesphere的离线部署&#xff0c;全新方式助力企业高效运维。" 本文将深入探讨如何借助鲲鹏CPU(arm64)和操作系统Kylin V10 SP2/SP3,通过KubeKey制作KubeSphere与Kubernetes的离线安装包&#…

「C/C++」C/C++ 之 指针详解

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

CSS--导航栏案例

利用CSS制作北大官网导航栏 详细代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}#menu{background-color: darkred;width: 100%;height: 50px…

【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割!

【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割&#xff01; 【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割&#xff01; 文章目录 【语义分割|代码解析】CMTFNet-2: …

基于 Python 的 Django 框架开发的电影推荐系统

项目简介&#xff1a;本项目是基于 Python 的 Django 框架开发的电影推荐系统&#xff0c;主要功能包括&#xff1a; 电影信息爬取&#xff1a;获取并更新电影数据。数据展示&#xff1a;提供电影数据的列表展示。推荐系统&#xff1a;基于协同过滤算法实现个性化推荐。用户系…

高并发场景下的性能测试方法!

在现代互联网应用中&#xff0c;高并发场景下的性能测试显得尤为重要。无论是电商平台的秒杀活动&#xff0c;还是社交应用的突发流量&#xff0c;都需要确保系统能够在高并发情况下稳定运行。本文将详细介绍高并发场景下的性能测试方法&#xff0c;并提供具体的方案和实战演练…

超萌!HTMLCSS:超萌卡通熊猫头

效果演示 创建了一个卡通风格的熊猫头 HTML <div class"box"><div class"head"><div class"head-copy"></div><div class"ears-left"></div><div class"ears-right"></di…

springboot高校运动会管理系统-计算机毕业设计源码33814

摘要 本文旨在介绍基于Spring Boot框架和HTML技术开发的高校运动会管理系统。通过该系统&#xff0c;学校能够更高效地组织和管理校园内的各项体育赛事&#xff0c;提升运动会的组织效率和参与体验。系统整合了Spring Boot的强大功能和HTML的灵活性&#xff0c;为高校运动会管理…

Linux特种文件系统--tmpfs文件系统

tmpfs类似于RamDisk&#xff08;只能使用物理内存&#xff09;&#xff0c;使用虚拟内存&#xff08;简称VM&#xff09;子系统的页面存储文件。tmpfs完全依赖VM&#xff0c;遵循子系统的整体调度策略。说白了tmpfs跟普通进程差不多&#xff0c;使用的都是某种形式的虚拟内存&a…

森利威尔SL2516D 耐压60V内置5V功率MOS 支持PWM LED恒流驱动器芯片

一、基本特性 型号&#xff1a;SL2516D封装&#xff1a;ESOP8工作频率&#xff1a;140kHz驱动MOS管&#xff1a;内置 二、电气特性 输入电压范围&#xff1a;8V~100V&#xff08;注意&#xff0c;虽然问题中提到耐压60V&#xff0c;但根据官方信息&#xff0c;其实际耐压范围…

力扣287.寻找重复数

1.哈希表法 #include<stdio.h> #include<stdlib.h> int func(int *arr,int len) {int *hash(int *)malloc(sizeof(int)*len);for(int i0;i<len;i){if(hash[arr[i]]1){free(hash);return arr[i];}hash[arr[i]]1;}free(hash);return -1; }int main() {int arr[5]{…

服务器数据恢复—DELL EqualLogic PS6100系列存储简介及如何收集故障信息?

DELL EqualLogic PS6100系列存储采用虚拟ISCSI SAN阵列&#xff0c;支持VMware、Solaris、Linux、Mac、HP-UX、AIX操作系统&#xff0c;提供全套企业级数据保护和管理功能&#xff0c;具有可扩展性和容错功能。DELL EqualLogic PS6100系列存储介绍&#xff1a; 1、上层应用基础…

【笔面试常见题:三门问题】用条件概率、全概率和贝叶斯推导

1. 问题介绍 三门问题&#xff0c;又叫蒙提霍尔问题&#xff08;Monty Hall problem&#xff09;&#xff0c;以下是蒙提霍尔问题的一个著名的叙述&#xff0c;来自Craig F. Whitaker于1990年寄给《展示杂志》&#xff08;Parade Magazine&#xff09;玛丽莲沃斯莎凡特&#x…

C++ | Leetcode C++题解之第526题优美的排列

题目&#xff1a; 题解&#xff1a; class Solution { public:int countArrangement(int n) {vector<int> f(1 << n);f[0] 1;for (int mask 1; mask < (1 << n); mask) {int num __builtin_popcount(mask);for (int i 0; i < n; i) {if (mask &am…

新160个crackme - 089-fornixcrackme1

运行分析 需要破解Name和Serial PE分析 ASM程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida搜索找到关键字符串 动态分析关键函数&#xff0c;逻辑如上图&#xff0c;通过Name计算得到char_1&#xff0c;亦或后对比Serial&#xff0c;相等则返回成功信息 分析…

【测试平台】打包 子节点ios环境配置

主要记录如何配置ios打包机环境&#xff0c;ios环境相对来说比较简单的&#xff0c;研发配置好证书可以本地打包&#xff0c;接入流程比较简单了。 打包机系统升级 1.升级mac OS系统 一般升级好几个小时&#xff0c;可以晚上下载好 2.下载xcode并安装 Appstroe 下载安装xco…

【AIGC】深入探索『后退一步』提示技巧:激发ChatGPT的智慧潜力

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;“后退一步”技巧介绍技巧目的 &#x1f4af;“后退一步”原理“后退一步”提示技巧与COT和TOT的对比实验验证 &#x1f4af;如何应用“后退一步”策略强调抽象思考引导提…

Java后端面试内容总结

先讲项目背景&#xff0c;再讲技术栈模块划分&#xff0c; 讲业务的时候可以先讲一般再特殊 为什么用这个&#xff0c;好处是什么&#xff0c;应用场景 Debug发现问题/日志发现问题. QPS TPS 项目单元测试&#xff0c;代码的变更覆盖率达到80%&#xff0c;项目的复用性高…

TI-Trends in Immunotherapy

文章目录 一、征稿简介二、重要信息三、服务简述四、投稿须知五、联系咨询 一、征稿简介 二、重要信息 期刊官网&#xff1a;https://ais.cn/u/3eEJNv 三、服务简述 Trends in Immunotherapy 是一本开放获取的同行评审期刊&#xff0c;涵盖与所有基于免疫系统的领域相关的各…