C++vector部分实现及感悟

myvector.h
#pragma once
#include<assert.h>
#include<iostream>
#include<vector>
using namespace std;
namespace bit {template<class T>//必须使用typename场景\template<typename T>与template<class T>一般情况下这两个通用,但有一个特例,就是当 T 是一个类,而这个类又有子类(假设名为 innerClass) 时,应该用 template<typename>:\typename T::innerClass myInnerObject; 这里的 typename 告诉编译器,T::innerClass 是一个类,程序要声明一个 T::innerClass 类的对象,而不是声明 T 的静态成员,而 typename 如果换成 class 则语法错误。class vector{public:typedef T* iterator;typedef const T* const_iterator;//const指针得到const迭代器,非const得非const迭代器const_iterator begin()const{return _start;}const_iterator end()const{return _end;}iterator begin(){return _start;}iterator end(){return _end;}// 类模板的成员函数
// 函数模板 -- 目的支持任意容器的迭代器区间初始化template<class InputIterator>vector(InputIterator it_begin, InputIterator it_end){while (it_begin != it_end){push_back(*(it_begin++));}}vector() = default;vector(size_t n, const T& val = T()){reserve(n);//尽量一次性开空间for (size_t i = 0; i < n; i++)//和n同一类型大小push_back(val);}vector(initializer_list<T> il){reserve(il.size());//要push_back,insert等频繁插入数据就想优化一次插入for (auto& e : il)//初始列表支持迭代器就支持范围for从头往后{push_back(e);}}vector(int n, const T& val = T())//要有int版本的不然传两个数字为int与迭代器模板函数混淆{reserve(n);//尽量一次性开空间for (int i = 0; i < n; i++)//和n同一类型大小push_back(val);}vector(const vector<T>& v){//拷贝构造实现深度拷贝reserve(v.capacity());for (auto& e : v){push_back(e);}}void swap(vector<T>&v){std::swap(this->_start, v._start);std::swap(this->_end, v._end);std::swap(this->_end_of_storage, v._end_of_storage);}vector<T>& operator=(vector<T> v)//现代写法,可以传参的拷贝实参,深拷贝再交换自动析构{swap(v);return *this;//可以连续运算的返回其值}~vector(){if (_start){delete[] _start;_start = _end_of_storage = _end = nullptr;}}void reserve(size_t n)//size_t{//不能用memcpy拷贝新旧空间,浅拷贝的空间会析构两次if (n > capacity()){size_t oldsizes = size();iterator new_start = new T[n];for (size_t i = 0; i < oldsizes; i++){new_start[i] = _start[i];}delete[] _start;_start = new_start;_end = _start + oldsizes;_end_of_storage = _start+n;}}size_t capacity()const //仅访问的允许常this指针{return _end_of_storage - _start;}size_t size()const{return _end - _start;}T& operator[](size_t n){assert(n < size());//访问越界检查return _start[n];}const T& operator[](size_t n)const//常指针访问返回常引用[]{assert(n < this->size());return _start[n];}void push_back(const T& val){//if (_end == _end_of_storage)//{//	size_t capacity = capacity() == 0 ? 4 : 2 * capacity();//	reserve(capacity);//}//*_end++ = val;//后置++优先级大于解引用insert(end(), val);}void popback(){assert(size());--_end;}iterator insert(iterator pos, const T& val)//pos迭代器不能传引用,不然外部不能拷贝传参临时变量引用,insert(t.begin()->传的临时变量不能传普通引用{//这里形参如果是引用的话,则编译时会报错,因为v.begin()返回的是一个临时变量,自定义类型传值拷贝返回,返回临时变量再拷贝给接收的,是一个右值,它不能赋值给一个非const的引用: assert(pos <= _end);assert(pos >= _start);if (_end == _end_of_storage){size_t len = pos - _start;size_t capacity = this->capacity() == 0 ? 4 : this->capacity() * 2;reserve(capacity);pos = _start + len;//内部迭代器更新}iterator end = _end-1;while (end >= pos){*(end + 1)=*end;end--;}_end++;*pos = val;return pos;}iterator erase(iterator pos){assert(pos < _end);assert(pos >= _start);iterator pos_i = pos+1;while (pos_i < _end)*(pos_i - 1) = *pos_i++;--_end;return pos;}private://在类型定义后写iterator _start = nullptr;iterator _end = nullptr;iterator _end_of_storage = nullptr;};
}
void test01()
{bit::vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);size_t size = v1.size();for (int i = 0; i < size; i++)cout << v1[i] << endl;for (const auto& e : v1)cout << e << endl;bit::vector<int>::iterator it_begin = v1.begin();bit::vector<int>::iterator it_end = v1.end();for (; it_begin < it_end; it_begin++)cout << *it_begin << endl;}void test02()
{bit::vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.insert(v1.begin(), 0);size_t size = v1.size();for (int i = 0; i < size; i++)cout << v1[i] << " ";cout << endl;for (const auto& e : v1)cout << e << " ";cout << endl;v1.erase(v1.end() - 1);bit::vector<int>::iterator it_begin = v1.begin();bit::vector<int>::iterator it_end = v1.end();for (; it_begin < it_end; it_begin++)cout << *it_begin << " ";cout << endl;int x;cin >> x;bit::vector<int>::iterator pos_x = find(v1.begin(), v1.end(), x);//模板实例化才能找类域if (pos_x != v1.end()){pos_x =v1.insert(pos_x, 1000);// 建议失效后迭代器不要访问。除非赋值 更新 一下这个失效的迭代器cout << *pos_x << endl;}for (const auto& e : v1)cout << e << " ";cout << endl;}
void test03()
{std::vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);int x;cin >> x;std::vector<int>::iterator it = find(v1.begin(), v1.end(), x);if (it != v1.end()){// erase it以后,it是否失效呢?失效it = v1.erase(it);if (it != v1.end())cout << *it << endl;}cout << typeid(it).name() << endl;
}
void test_vector4()
{std::vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);std::vector<int>::iterator it = v1.begin();while (it < v1.end())//用迭代器遍历并删除偶数{if (*it % 2 == 0){it = v1.erase(it);}else++it;}for (auto e : v1){cout << e << " ";}cout << endl;
}
void test_vector5()
{bit::vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);bit::vector<int> v2(v1);for (auto e : v2){cout << e << " ";}cout << endl;bit::vector<int> v3;v3.push_back(10);v3.push_back(20);v3.push_back(30);v1 = v3;for (auto e : v1){cout << e << " ";}cout << endl;
}
void test_vector07()
{int i = int();int k(2);int f = { 3 };int h = int(7);int j{ 1 };
}

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

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

相关文章

Jmeter实战教程入门讲解

前言 通过前面对Jmeter元件的讲解&#xff0c;大家应该都知道常用元件的作用和使用了。编写Jmeter脚本前我们需要知道Jmeter元件的执行顺序&#xff0c;可以看看我这篇性能测试学习之路&#xff08;三&#xff09;—初识Jmeter来了解下。下面我将以工作中的一个简单的实例带大…

Flutter 中的 TableCell 小部件:全面指南

Flutter 中的 TableCell 小部件&#xff1a;全面指南 Flutter 是一个功能强大的 UI 框架&#xff0c;由 Google 开发&#xff0c;允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的丰富组件库中&#xff0c;TableCell 是一个用于创建表格单元格的组件…

企业打款验证API在Java、Python、PHP中的使用教程

随着企业银行账号数量的增加和银行间的连接方式不断丰富&#xff0c;企业在进行资金交易时需要确保所填写的收款方账户信息的准确性和合法性&#xff0c;以避免资金损失和风险。然而&#xff0c;由于银行数量众多、地域分布广泛&#xff0c;不同银行间的账户验证机制和信息交互…

vue前端实现页面禁止缩放 前端适配问题处理 前端项目多端适配解决方案

在前端项目中,如果一个系统页面可以缩放可能会导致多种异常情况,这些异常情况涉及到页面布局、元素尺寸、事件触发、响应式设计和用户体验等方面。 1.布局错乱:页面元素在缩放后可能会出现错位、重叠或部分隐藏的情况,导致页面布局混乱,影响用户对页面内容的理解和操作。这…

【云原生】kubernetes中secret原理详解与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

读AI未来进行式笔记02深度伪造

1. 计算机视觉 1.1. 在人的六感之中&#xff0c;视觉是最重要的 1.1.1. 人类只要看上一眼视频&#xff0c;就能瞬间在脑海中抓取并消化内容和信息 1.1.2. 人类能够对事物进行广义的理解和抽象的认知&#xff0c;即使同一物体在不同的角度…

声量2024 | 内容创作者,该怎样保护你的知识产权

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 阿那亚 联合制作 / 声量The Power of Voice 特别鸣谢 / 深夜谈谈播客网络 本期节目录制于第二届「声量The Power of Voic…

opencascade 布尔运算笔记

BRepAlgoAPI_Common 对两个topods求解 没有公共部分也返回结果了 我想要的结果是没有公共部分返回false 在 Open CASCADE 中使用 BRepAlgoAPI_Common 进行布尔操作时&#xff0c;即使两个 TopoDS_Shape 没有公共部分&#xff0c;操作仍会返回一个结果。为了判断两个形状是否确…

vue3封装echarts组件---通俗易懂

1、封装的原因 如果在vue项目中有多个组件或者同个组件多出地方需要不同的图表&#xff0c;因此自己封装一个方便多次复用的Mycharts图表组件。 2、具体步骤&#xff1a; 2.1 安装echarts pnpm i echarts --save 2.2 新建MyCharts组件 : ~components/echarts/MyCharts.vu…

x264 参考帧管理原理:i_poc 变量

POC H.264中的POC(Picture Order Count)用于表示解码帧的显示顺序。当视频码流中存在B帧时,解码顺序和显示顺序可能不一致,因此需要根据POC来重新排列视频帧的显示顺序,以避免跳帧或画面不连贯的问题。 具体来说,POC的作用包括: 重排显示顺序:POC确保即使在存在B帧的情…

基于javacv ffmpeg 使用原生ffmpeg命令

基于javacv ffmpeg 使用原生ffmpeg命令 1. ffmpeg2. ffprobe 相关阅读&#xff1a; javacv ffmpeg使用笔记 测试过程中&#xff0c;发现ffmpeg-6.0-1.5.9-linux-x86_64.jar 存在问题&#xff08;ffmpeg原生命令执行失败&#xff09;&#xff0c;降级到ffmpeg-5.1.2-1.5.8-linux…

RPG Maker MV 踩坑十一 精灵及背景绘制问题

精灵绘制问题 RPG Maker MV战斗问题入场飞身战斗背景绘制精灵集及精灵 RPG Maker MV战斗问题 在RMMV中战斗是在场景中调用战斗管理器&#xff0c;通过管理器去操作角色对象行动及精灵的绘制的。 入场飞身 在其中就发现一个问题加载图片进场时&#xff0c;会偏高&#xff0c;…

Python编程学习第一篇——Python零基础快速入门(五)—元组(Tuple)操作

Python元组是一种不可变的有序集合&#xff0c;可以存储多个不同类型的数据。元组使用小括号来表示&#xff0c;其中的元素用逗号分隔开。与列表不同&#xff0c;元组的元素不能被修改、删除或添加。它的一些常规操作包括元组的创建、访问、添加、修改、删除、运算等等&#xf…

电力电子功率模块在工程应用中测温NTC的使用

电力电子功率模块在工程应用中测温NTC的使用 1.概述2.什么是NTC3.模块内部NTC3.1 绝缘隔离措施3.2 NTC热量考虑 4.使用模拟方法测量NTC温度4.1 分压电阻大小 5.使用数字方法测量NTC温度 1.概述 最近做项目的时候突然被问到一个问题。做实验测温用的NTC到底怎么用&#xff1f;为…

【Python】超时请求或计算的处理

超时机制 一般应用于处理阻塞问题 场景&#xff1a; 复杂度较大的计算&#xff08;解析&#xff09;某个数值、加解密计算等请求中遇到阻塞&#xff0c;避免长时间等待网络波动&#xff0c;避免长时间请求&#xff0c;浪费时间 1. requests 请求超时机制 reqeusts 依赖中的…

[大师C语言(第十九篇)]C语言函数式编程技术详解

引言 函数式编程&#xff08;Functional Programming&#xff0c;FP&#xff09;是一种编程范式&#xff0c;强调通过使用纯函数和不可变数据来编写代码。这种范式具有许多优点&#xff0c;如易于测试、可维护性高、并发友好等。尽管C语言被认为是一种过程式编程语言&#xff…

JAVA设计模式-策略模式及在Springboot2.X中写法

JAVA设计模式-策略模式及在Springboot2.X中写法 一、经典的策略模式写法二、Springboot2.X中策略模式写法 策略模式的定义&#xff1a;策略模式是一种行为型设计模式,定义了一系列算法,并将每个算法封装起来,使它们可以互相替换 策略模式&#xff1a;在策略模式&#xff08;Str…

算法 java 排序和查找

排序和查找 冒泡排序&#xff08;稳定&#xff09;选择排序&#xff08;不稳定&#xff09;插入排序&#xff08;稳定&#xff09;希尔排序&#xff08;不稳定&#xff09;归并排序&#xff08;稳定&#xff09;快速排序&#xff08;不稳定&#xff09;堆排序计数排序桶排序基数…

YOLOv8+PyQt5海洋船只检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)

1.效果视频&#xff1a;海洋船只检测yoloV8检测&#xff08;https://mbd.pub/o/bread/mbd-ZpaYk55r&#xff09;_哔哩哔哩_bilibili资源包含可视化的海洋船只检测系统&#xff0c;可对于高空拍摄到的海洋图片进行轮船检测&#xff0c;基于最新的YOLOv8训练的海洋船只检测模型&a…

多线程知识-11

Runnable 和 Thread 用哪个好 使用Runnable接口的好处是&#xff1a; 避免了单继承的限制&#xff1a;当你的类已经继承了另一个类时&#xff0c;你仍然可以实现Runnable接口来创建线程。提高代码的复用性&#xff1a;你可以将Runnable对象传递给多个线程来执行&#xff0c;从…