C++STL简介(三)

目录

1.vector的模拟实现

 1.1begin()

 1.2end()

 1.3打印信息

 1.4 reserve()

 1.5 size()

 1.6 capacity()

 1.7 push_back()

 1.8[ ]

 1.9 pop_back()

 1.10 insert()

 1.11拷贝构造

1.12析构函数

 1.13 =

 1.14chear

 1.15区间构造

 1.16默认构造

 2.完整代码

 3.迭代器失效问题

1.类似野指针

​编辑2.位置意义变了


C++ 中的 vector 是一种序列容器,它允许你在运行时动态地插入和删除元素。

vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。

与 C++ 数组相比,vector 具有更多的灵活性和功能,使其成为 C++ 中常用的数据结构之一。

vector 是 C++ 标准模板库(STL)的一部分,提供了灵活的接口和高效的操作。

基本特性:

  • 动态大小vector 的大小可以根据需要自动增长和缩小。
  • 连续存储vector 中的元素在内存中是连续存储的,这使得访问元素非常快速。
  • 可迭代vector 可以被迭代,你可以使用循环(如 for 循环)来访问它的元素。
  • 元素类型vector 可以存储任何类型的元素,包括内置类型、对象、指针等。

使用场景:

  • 当你需要一个可以动态增长和缩小的数组时。
  • 当你需要频繁地在序列的末尾添加或移除元素时。
  • 当你需要一个可以高效随机访问元素的容器时。

1.vector的模拟实现

基本框架

namespace V
{template<class T>class vector{public:typedef T* iterator;typedef  const T* const_iterator;iterator _start=nullptr;//开始iterator _finish=nullptr;//存数据iterator _end_of_storage=nullptr;//结束};

 1.1begin()

开始位置的迭代器

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

 1.2end()

结束位置的迭代器

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

 1.3打印信息

template<class T>void print_vector(const  vector<T>& v){//没有实例化的类模板里面取东西,编译器不能区分这里const_iterator是类型还是静态成员变量typename vector<T>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;for (auto e : v){cout << e << " ";cout << endl;}}typename void print_vector(  vector<T>& v){vector<T>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;for (auto e : v){cout << e << " ";cout << endl;}}

 1.4 reserve()

扩容

	void reserve(size_t n){if (n > capacity()){size_t old_size = size();T* tmp = new T[n];memcpy(tmp, _start, size() * sizeof(T));delete[] _start;_finish =  tmp + old_size();_start = tmp;_end_of_storage = _start + n;}}

 1.5 size()

内容个数

size_t size(){return _finish - _start;}

 1.6 capacity()

容量

size_t capacity(){return _end_of_storage - _start;}

 1.7 push_back()

尾插

	void push_back(const T& x){if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;}

 1.8[ ]

下标访问

T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}bool empty(){return _start == _finish;}

 1.9 pop_back()

尾删

void pop_back(){assert(empty());--_finish;}

 1.10 insert()

插入

	void insert(iterator pos, const T& x){if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator end = _finsh - 1;while (end>=pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}

 1.11拷贝构造

vector(const vector<T>& v)
{reserve(v.size());for (auto& e : v){push_back(e);}
}

1.12析构函数

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

 1.13 =

vector<T>& operator=(const vector<T>& v)
{if (this != &v){chear();reserve(v.size());for(ayto& 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=(vextor<T> v)
{swap(v);return *this;
}

 1.14chear

清除数据

	void clear(){_finish = _start;}

 1.15区间构造

	//类模板的成员函数还可以继续是函数模板//区间构造template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++firsh;}}

 

 1.16默认构造

n个T()初始化

	vector(size_t n ,const T& val=T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}

 2.完整代码

#include<iostream>
#include<assert.h>
#define _CRT_SECURE_NO_WARNINGS 1
using namespace std;
namespace V
{template<class T>class vector{public:typedef T* iterator;typedef  const T* const_iterator;vector(){}vector(const vector<T>& v){reserve(v.size());for (auto& e : v){push_back(e);}}~vector(){if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}template<class T>void print_vector(const  vector<T>& v){//没有实例化的类模板里面取东西,编译器不能区分这里const_iterator是类型还是静态成员变量typename vector<T>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;for (auto e : v){cout << e << " ";cout << endl;}}typename void print_vector(  vector<T>& v){vector<T>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;for (auto e : v){cout << e << " ";cout << endl;}}void reserve(size_t n){if (n > capacity()){size_t old_size = size();T* tmp = new T[n];memcpy(tmp, _start, size() * sizeof(T));delete[] _start;_finish =  tmp + old_size();_start = tmp;_end_of_storage = _start + n;}}size_t size(){return _finish - _start;}size_t capacity(){return _end_of_storage - _start;}void push_back(const T& x){if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;}T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}void clear(){_finish = _start;}
/*		vector<T>& operator=(const vector<T>& v){if (this != &v){chear();reserve(v.size());for(ayto& 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;}//类模板的成员函数还可以继续是函数模板//区间构造template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++firsh;}}vector(size_t n ,const T& val=T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}bool empty(){return _start == _finish;}void pop_back(){assert(empty());--_finish;}void insert(iterator pos, const T& x){if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator end = _finish - 1;while (end>=pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}private:iterator _start=nullptr;//开始iterator _finish=nullptr;//存数据iterator _end_of_storage=nullptr;//结束};}

 3.迭代器失效问题

1.类似野指针

最开始_finish=_start=_end_of_storage=0;经过扩容,_start已经不为nullptr了,用一个nullptr减一个地址,用扩容前的地址减去扩容后的地址,_finish访问后地址就类似野指针,本意是想_finish存储最后一个数据的地址,可是实际差强人意这段代码肯定有问题但是编译器不报错

 修正一下,用old_size存储相对位置在进行计算就更合理

	void reserve(size_t n){if (n > capacity()){size_t old_size = size();T* tmp = new T[n];memcpy(tmp, _start, size() * sizeof(T));delete[] _start;_finish =  tmp + old_size();_start = tmp;_end_of_storage = _start + n;}}

 

1.2

 扩容后,pos还指向旧空间,while循环end-pos次,迭代器失效

 任然是用相对位置

void insert(iterator pos, const T& x){if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator end = _finsh - 1;while (end>=pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}

  pos被释放后失效了虽然后面修正了形参的改变不影响实参实参仍然指向旧空间,访问旧空间,迭代器失效

2.位置意义变了

 

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

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

相关文章

合并K个有序链表

题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例1&#xff1a; 输入&#xff1a; 输出&#xff1a; 示例2&#xff1a; 输入&#xff1a; 输出&#xff1a; 示例3&#xff1a; 输入&…

【音视频之SDL2】Windows配置SDL2项目模板

文章目录 前言 SDL2 简介核心功能 Windows配置SDL2项目模板下载SDL2编译好的文件VS配置SDL2 测试代码效果展示 总结 前言 在开发跨平台的音视频应用程序时&#xff0c;SDL2&#xff08;Simple DirectMedia Layer 2&#xff09;是一个备受欢迎的选择。SDL2 是一个开源库&#x…

自研Vue3开源Tree组件:节点拖拽bug修复

当dropType为after&#xff0c;且dropNode为父节点时&#xff0c;bug出现了&#xff1a; bug原因&#xff1a;插入扁平化列表的位置insertIndex计算的不对&#xff1a; 正确的逻辑&#xff0c;同inner要算上子孙节点所占的位置&#xff1a; bug修复&#xff01;

「数组」实现动态数组的功能(C++)

概述 动态数组&#xff0c;顾名思议即可变长度的数组。数组这种数据结构的实现是在栈空间或堆空间申请一段连续的可操作区域。 实现可变长度的动态数组结构&#xff0c;应该有以下操作&#xff1a;申请一段足够长的空间&#xff0c;如果数据的存入导致空间已满&#xff0c;则…

PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法:

PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法&#xff1a; PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法&#xff1a; 1. 更换镜像源 虽…

rust 桌面 sip 软电话(基于tauri 、pjsip库)

本文尝试下rust 的tauri 桌面运用 原因在于体积小 1、pjsip 提供了rust 接口官方的 rust demo 没编译出来 在git找了个sip-phone-rs-master https://github.com/Charles-Schleich/sip-phone-rs 可以自己编译下pjsip lib库替换该项目的lib 2、创建一个tauri demo 引用 [depe…

计算机毕业设计选题推荐-某炼油厂盲板管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

实战:Zookeeper 简介和单点部署ZooKeeper

Zookeeper 简介 ZooKeeper是一个开源的分布式协调服务&#xff0c;它是Apache软件基金会下的一个项目&#xff0c;旨在解决分布式系统中的协调和管理问题。以下是ZooKeeper的详细简介&#xff1a; 一、基本定义 ZooKeeper是一个分布式的、开放源码的分布式应用程序协调服务&a…

SpringBoot的基础配置

目录 SpringBoot快速搭建web程序 第一步&#xff1a;导包 第二步&#xff1a;配置SpringBoot引导类 第三步&#xff1a;编写controller类 第四步&#xff1a;在SpirngBoot引导类中启动项目 起步依赖 SpringBoot基础配置 配置文件格式 yaml语法规则 读取yml配置文件的方…

UE5+OpenCV配置(Windows11系统)

一、概述 因为需要在UE5中使用OpenCV这些工具进行配置&#xff0c;所以在网络上参考借鉴一些资料进行配置。查询到不少的资料&#xff0c;最后将其配置成功。在这里顺便记录一下自己的配置成功的过程。 二、具体过程 &#xff08;一&#xff09;版本 使用Windows11系统、UE5.…

ONLYOFFICE 协作空间 2.6 已发布:表单填写房间、LDAP、优化房间和文件管理等

更新后的 ONLYOFFICE 协作空间带来了超过 20 项新功能和优化&#xff0c;让工作更加高效和舒适。阅读本文了解详情。 表单填写房间 这次更新增加了一种新的房间类型&#xff0c;可在 ONLYOFFICE 协作空间中组织简单的表单填写流程。 通过表单填写房间&#xff0c;目前可以完成…

将控制台内容输出到文本文件

示例代码&#xff1a; Imports System.IO Module Module1Sub Main()Dim fs As New FileStream("D:\Desktop\test\输出结果.txt", FileMode.Create, FileAccess.Write, FileShare.None)Dim sw As New StreamWriter(fs)Console.SetOut(sw)Console.SetError(sw)For i …

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第四篇 嵌入式Linux系统移植篇-第六十九章uboot移植

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

移动UI:排行榜单页面如何设计,从这五点入手,附示例。

移动UI的排行榜单页面设计需要考虑以下几个方面&#xff1a; 1. 页面布局&#xff1a; 排行榜单页面的布局应该清晰明了&#xff0c;可以采用列表的形式展示排行榜内容&#xff0c;同时考虑到移动设备的屏幕大小&#xff0c;应该设计合理的滚动和分页机制&#xff0c;确保用户…

在线教育数仓项目(数据采集部分1)

文章目录 数据仓库概念项目需求及架构设计项目需求分析系统数据流程设计框架版本选型集群规模估算集群资源规划设计 数据生成模块目标数据页面事件曝光启动播放错误 数据埋点主流埋点方式&#xff08;了解&#xff09;埋点数据上报时机埋点数据日志结构 服务器和JDK准备服务器准…

Linux:shell的基础用法

shell的基础用法 shell变量 Shell 支持以下三种定义变量的方式&#xff1a; valueabcvalue‘abc’value“abc”(注意&#xff0c;赋值号的周围不能有空格) Shell 变量的命名规范 变量名由数字、字母、下划线组成必须以字母或者下划线开头不能使用 Shell 里的关键字&#xff08…

IDEA的pom.xml显示ignored 的解决办法

问题&#xff1a; idea中创建Maven module时&#xff0c;pom.xml出现ignored。 原因&#xff1a; 相同名称的module在之前被创建删除过&#xff0c;IDEA会误以为新的同名文件是之前删除掉的&#xff0c;将这个新的module的pom.xml文件忽略掉显示ignored. 解决&#xff1a; 在…

springboot超市商品管理系统-计算机毕业设计源码55289

摘 要 随着信息技术的快速发展和普及&#xff0c;传统的超市管理模式已经无法满足现代商业的需求。为了提高超市的管理效率&#xff0c;优化商品销售流程&#xff0c;本文提出了一种基于SpringBoot框架的超市商品管理系统。该系统结合了现代软件开发技术&#xff0c;包括MySQL数…

WATLOW Power Series SSR User’s Manual

WATLOW Power Series SSR User’s Manual

【Java】字符串String类(011)

目录 ♦️API和API帮助文档 ♦️创建String &#x1f38f;直接赋值类 &#x1f38f;new类 &#x1f421;空参类 构造方法&#xff1a; 举例代码&#xff1a; &#x1f421;有参类 构造方法&#xff1a; 举例代码&#xff1a; &#x1f421;字符数组类 构造方法&…