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 };
}
相关文章:
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>一般情况下这两个通用&#…...
MySql什么时候表锁or行锁?
文章目录 锁的基本概念共享锁(读锁)排他锁(写锁)锁的兼容性锁的升级和降级 全局锁、表锁、行锁全局锁表锁行锁 何时使用行锁何时使用表锁额外思考: 在数据库的世界里,性能优化是一个永恒的话题。MySQL作为广…...

Stable Diffusion WebUI详细使用指南
Stable Diffusion WebUI(AUTOMATIC1111,简称A1111)是一个为高级用户设计的图形用户界面(GUI),它提供了丰富的功能和灵活性,以满足复杂和高级的图像生成需求。由于其强大的功能和社区的活跃参与&…...
Android中focusableInTouchMode会导致第一次点击事件失效
我们很多时候会对某些View设置点击事件,但是,当对这个View同时设置了focusableInTouchModetrue时,第一次点击事件会被消费为为此View获取焦点。 <Viewandroid:id"id/v_click"android:layout_width"match_parent"andr…...

C语言| 输出菱形*(梳理篇II)
C语言| 输出菱形*-CSDN博客 凡事还是得自己独立思考后,写一遍程序才能发现问题所在。 容易犯的错误: 【完整程序注释】 运行结果 /* 输出菱形 1 总行数 n为奇数,分上三角形下三角形,只考虑左边的空格和星号* 2 上三角形 行数…...
conda使用
因为时不时搜索conda操作,就想着逐步将先前的conda使用整理在一起,并添加新的内容。 目录 0.简介1.常用操作场景1.1 取消终端conda自动启动 0.简介 1.常用操作场景 1.1 取消终端conda自动启动 安装conda后取消命令行前出现的base,取消每次…...

适合小白学习的项目1949java图片管理系统 Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java图片管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助采用了java设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发 环境为TOMCAT7.0,Myeclipse8.5开发&…...

Jmeter实战教程入门讲解
前言 通过前面对Jmeter元件的讲解,大家应该都知道常用元件的作用和使用了。编写Jmeter脚本前我们需要知道Jmeter元件的执行顺序,可以看看我这篇性能测试学习之路(三)—初识Jmeter来了解下。下面我将以工作中的一个简单的实例带大…...
Flutter 中的 PrimaryScrollController 小部件:全面指南
Flutter 中的 PrimaryScrollController 小部件:全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架,它允许开发者使用 Dart 语言构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的滚动机制中,PrimaryScrollController 起着至关重…...
Windows线程同步的四种方式和区别
1. Windows线程同步的四种方式 2. 区别 Critical Section更多强调的是保护,Event对象、Mutex对象与Semaphore对象更多的强调的是同步;Critical Section对象是无法设置等待超时的,而其他三个对象则可以设置等待超时,从这一点来讲…...
C++ 20新特性之Concepts
C20的新特性之一Concepts,为C的模板编程带来了重大的改进和便利。以下是关于C20中Concepts特性的详细介绍: 基本概念 定义:Concepts是C20中引入的一种新的语言特性,用于限制类和函数模板的模板类型和非类型参数。它允许你为模板编…...
MATLAB基础应用精讲-【数模应用】SPSSAU数据处理
目录 SPSSAU 标题修改 1、说明 2、举例 数据标签 1、说明 2、举例...

AI大模型探索之路-实战篇15: Agent智能数据分析平台之整合封装Tools和Memory功能代码
系列篇章💥 AI大模型探索之路-实战篇4:深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5:探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6:掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…...

CV每日论文--2024.6.4
1、Mixed Diffusion for 3D Indoor Scene Synthesis 中文 标题:用于 3D 室内场景合成的混合扩散 简介:这篇论文提出了一种名为MiDiffusion的混合离散-连续扩散模型,用于从给定的房间类型、平面图和可能存在的物体中合成逼真的3D室内场景。 作者指出,该…...
Android bw_costly_<iface>链
测试时关注到bw_costly_链 因为和iface有关。猜测这个链是动态生成的。 开关数据业务测试,果然关闭数据业务后,bw_OUTPUT中不再会调用bw_costly_rmnet_data3,也没有bw_costly_rmnet_data3这个链了。 再次打开数据业务后出现了bw_costly_rmnet…...
TypeScript 项目,自身 package 是 A,它引用了 B package。项目编译时,选择依赖版本的机制是什么?
在 TypeScript 项目中,当 package A 引用了 package B,编译 A 的过程中,B package 将按照 B package 自身的 package.json 文件中指定的各个库的版本进行编译,而不是按照 A package 中的库版本。 每个 package 都有自己的依赖项和…...
【数据结构】链表----头结点的作用
链表是一种常见的数据结构,由一系列节点(Node)组成,每个节点包含数据和指向下一个节点的指针。链表的头结点(Head Node)也称为哨兵位,是链表的起点,通常有以下几个重要作用ÿ…...

(CVPRW,2024)可学习的提示:遥感领域小样本语义分割
文章目录 相关资料摘要引言方法训练基础类别新类别推理 相关资料 论文:Learnable Prompt for Few-Shot Semantic Segmentation in Remote Sensing Domain 代码:https://github.com/SteveImmanuel/OEM-Few-Shot-Learnable-Prompt 摘要 小样本分割是一项…...

tinyrenderer-切线空间法线贴图
法线贴图 法线贴图分两种,一种是模型空间中的,一种是切线空间中的 模型空间中的法线贴图的rgb代表着每个渲染像素法线的xyz,与顶点坐标处于一个空间,图片是五颜六色的。 切线空间中的法线贴图的rgb同样对应xyz,是切线…...

C++的vector使用优化
我们在上一章说了如何使用这个vector动态数组,这章我们说说如何更好的使用它以及它是如何工作的。当你创建一个vector,然后使用push_back添加元素,当当前的vector的内存不够时,会从内存中的旧位置复制到内存中的新位置,…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...