C++入门 vector部分模拟实现

目录

vector大致框架

vector常见接口模拟实现

begin迭代器 & end迭代器

capacity( ) & size( )

reserve

operator[ ]

push_back( ) & pop_back( )

sort


vector大致框架

vector的内部的成员变量大概有三部分构成:

namespace bit
{
	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;     //记录容量
	};

这里成员变量的iterator可以理解为指针类型,但实际上并不是指针。具体框架就如上vector所示,这里不难发现,vector利用的是模板,意味着vector可以利用string等类型来搭建顺序表。


vector常见接口模拟实现

既然刚刚解释了iterator,那我们先模拟实现begin迭代器和end迭代器:

begin迭代器 & end迭代器

const_iterator begin() const
{
	return _start;
}

const_iterator end() const
{
	return _finish;
}

iterator begin()
{
	return _start;
}

iterator end()
{
	return _finish;
}

begin直接返回头元素地址,end直接返回尾元素地址。


capacity( ) & size( )

根据上文的三个成员变量,我们可以设计出以下的代码来反映vector的元素个数和容量大小。

size_t capacity()
{
	return _end_of_storage - _start;
}

size_t size()
{
	return _finish - _start;
}

由图可知, end与start相减是元素个数,end of storage与start相减是容量大小。

思考:为什么两个指针相减可以算出元素个数?

答案:指针相减的结果:例如两个整型指针的地址相差8个字节,但是相减的结果为2,是因为两个指针相减操作会对其结果除以该指针所代表的数据类型的字节数,此处整型数据类型有4个字节,所以指针相减结果为2.


reserve

void reserve(size_t n)
{
	if (n > capacity())
	{
		size_t oldsize = size();
		T* tmp = new T[n];

		if (_start)
		{
			memcpy(tmp, _start, sizeof(T) * size());
			delete[] _start;
		}

		_start = tmp;
		_finish = _start + oldsize;
		_end_of_storage = _start + n;
	}
}

思考一下,为什么reserve的空间大于容量大小要开辟空间?如下图所示:

 如果我们直接在原空间扩容,需要计算多扩容的个数,并且无法控制扩容的位置是否连续,对此应对这个问题,我们通过另外开辟一个n大小的空间进行memcpy。


operator[ ]

T& operator[](size_t i)
{
	assert(i < size());

	return _start[i];
}

assert保证了不会越界访问,否则会断言。


push_back( ) & pop_back( )

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

void pop_back()
{
	assert(size() > 0);

	--_finish;
}

pop_back很好理解,尾删只需要把只需要将指向尾元素的指针往前移一位即可。

push_back就稍微麻烦,需要考虑扩容,如果不够需要另外开辟大小为原容量两倍的空间来拷贝原顺序表,并将需要尾插的元素放在finish指向的空间。


sort

另外介绍algorithm头文件中一个算法函数:排序。

具体使用方法如下代码所示:

void test_vector()
{
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(2);
	v1.push_back(30);
	v1.push_back(4);
	v1.push_back(44);
	v1.push_back(4);
	v1.push_back(40);
	v1.push_back(4);

	//sort(v1.begin()+1, v1.end()-1);				//除首尾元素的排序
	//sort(v1.begin(), v1.begin() + v1.size() / 2);	//只排序一半元素

	// 默认是升序
	// 此处为降序
	sort(v1.begin(), v1.end(), greater<int>());
	for (const auto& e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

int main()
{
	test_vector();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java中的日志

springboot自带slf4j框架和logback&#xff0c;我们可以移除spring的logging&#xff0c;然后再带入自己的日志框架。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusio…

Linux中tar压缩与解压缩

TAR是Unix/Linux中常用的归档工具&#xff0c;它可以对文件或目录进行打包但不压缩&#xff0c;或者配合其他工具进行压缩。 压缩文件或目录 以下是一些基本的tar压缩命令&#xff1a; 1.压缩单个文件&#xff1a; tar -cvf archive.tar file1 2.压缩多个文件&#xff1a; t…

毕业季带给我的五个启示

每到毕业季&#xff0c;校园里总是充满了复杂的情绪。有人欢笑&#xff0c;有人落泪。同样的四年大学生活&#xff0c;为何结局如此不同&#xff1f;本文将从多个角度探讨如何实现综合改变&#xff0c;解释在交友、机会和心态上的关键因素&#xff0c;揭示“慢就是快”的真理。…

Vulnhub--OS-HACKNOS-2.1

渗透复现 目标站点为wordpress&#xff0c;通过wpscan进行漏洞扫描发现漏洞插件 通过漏洞插件存在的目录穿越漏洞成功读取/etc/passwd文件中flag用户的密码 SSH登录flag用户后在备份文件中找到rohit用户的密码 切换rohit用户&#xff0c;rohit用户能够以root权限执行任何文…

colima配置docker镜像源

只在 colima ssh 环境下修改 docker 配置文件是无效的&#xff0c;我们需要修改 colima 配置文件才能使 docker 镜像源生效。 此时你需要进入到~/.colima/default目录下编辑colima.yaml文件。该文件是 colima 的配置文件。内容如下图所示&#xff0c;我这里配置了许多家的镜像源…

手写方法实现整型例如:123与字符串例如:“123“相互转化(下篇)

目录 一、前言 二、整型转化为字符串 1. 初始化变量 2.数字1转字符1 3.取出value中的每一项数字 4.将字符放入字符数组中 5.最终代码 三、最后 一、前言 本篇文章紧跟上篇文章&#xff0c;本片内容为整型转化为字符串类型。至于我为什么要分两篇文章&#xff0c;主要…

【2024最新精简版】Kafka面试篇

文章目录 Kafka和RabbitMQ什么区别讲一讲Kafka架构你们项目中哪里用到了Kafka?为什么会选择使用Kafka? 有什么好处 ?使用Kafka如何保证消息不丢失 ?消息的重复消费问题如何解决的 ?Kafka如何保证消费的顺序性 ?Kafka的高可用机制有了解过嘛 ?Kafka实现高性能的设计有了解…

大数据的发展,带动电子商务产业链,促进了社会的进步【电商数据采集API接口推动电商项目的源动力】

最近几年计算机技术在诸多领域得到了有效的应用&#xff0c;同时在多方面深刻影响着我国经济水平的发展。除此之外&#xff0c;人民群众的日常生活水平也受大数据技术的影响。 在这其中电子商务领域也在大数据技术的支持下&#xff0c;得到了明显的进步。虽然电子商务领域的发…

华为数通题库HCIP-821——最新最全(带答案解析)

单选11、某台路由器运行IS—IS,其输出信息如图所示&#xff0c;下列说法错误的是? A、邻居路由器的System-ID为0002.0200.2002 B、本路由器是DIS C、本路由器的区域号为49.0001 D、本路由器System-ID为0100.0000.1001 解析&#xff1a;根据输出信…

go语言day2

使用cmd 中的 go install &#xff1b; go build 命令出现 go cannot find main module 错误怎么解决&#xff1f; go学习-问题记录(开发环境)go: cannot find main module&#xff1b; see ‘go help modules‘_go: no flags specified (see go help mod edit)-CSDN博客 在本…

Linux系统及常用命令介绍

一.介绍 Linux一套免费使用和自由传播的类Unix操作系统&#xff0c;是一个遵循POSIX的多用户、多任务、支持多线程和多CPU的操作系统。Linux系统的说明可以自行百度&#xff0c;知道这几点即可&#xff1a; 1.Linux中一切都是文件&#xff1b; 2.Linux是一款免费操作系统&…

【for循环】最大跨度

【for循环】最大跨度 时间限制: 1000 ms 内存限制: 65536 KB 【题目描述】 【参考代码】 #include <iostream> using namespace std; int main(){ int n;int max 0, min 100;cin>>n;for(int i1; i<n; i1){int a;cin>>a;if(a>max){max a;}i…

【Mysql】DQL操作单表、创建数据库、排序、聚合函数、分组、limit关键字

DQL操作单表 1.1 创建数据库 •创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8;•将db1数据库中的 emp表 复制到当前 db2数据库 ** 1.2 排序** 通过 ORDER BY 子句,可以将查询出的结果进行排序 (排序只是显示效果,不会影响真实数据) 语法结构&#xff1a;…

MySQL进阶——SQL优化

目录 1插入数据 1.1 insert 1.2大批量插入数据 2主键优化 3 order by 优化 4 group by 优化 5 limit 优化 6 count 优化 6.1概述 6.2 count用法 7 update优化 1插入数据 1.1 insert 优化方案主要有3种 批量插入数据 Insert into tb_test values(1,Tom),(2,Cat)…

基于MATLAB仿真LFM线性调频信号

基于MATLAB仿真LFM线性调频信号 目录 前言 一、LFM信号简介 二、LFM信号基本原理 三、LFM信号仿真 四、代码 总结 前言 仿真中的接收信号&#xff0c;有时为了简单会直接用一个正弦波代替&#xff0c;但实际中接收到的信号极少是点频信号&#xff0c;一般都是PSK信号、OF…

6G时代,即将来临!

日前&#xff0c;由未来移动通信论坛、紫金山实验室主办的2024全球6G技术大会在南京召开。本次大会以“创新预见6G未来”为主题&#xff0c;在大会开幕式上发布了协力推进全球6G统一标准行动的倡议和紫金山科技城加速培育以6G技术引领未来产业行动计划。 在我国已开展第五代移动…

细说MCU的ADC模块单通道单次采样的实现方法

目录 一、工程依赖的硬件 二、设计目的 三、建立工程 1、配置GPIO 2、配置中断 3、配置串口 4、配置ADC 5、选择时钟源和Debug 6、配置系统时钟和ADC时钟 四、设置采样频率 五、代码修改 1、重定义外部中断回调函数 2、启动ADC 3、配置printf函数 六、运行并…

C++之模板(二)

1、类模板 2、使用类模板 类模板在使用的时候要显示的调用是哪种类型&#xff0c;而不是像函数模板一样能够根据参数来推导出是哪种类型。 Stack.h #include <stdexcept>template <typename T> class Stack { public:explicit Stack(int maxSize);~Stack();void …

基于Java实训中心管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

ciscn_2019_n_1

前戏--------checksec,运行查看 进入就可以发现这段代码 很浅显易懂 我们要得到的后面是 这里 我们要利用的漏洞是 get函数 0x30大小 加上8 exp: from pwn import * ghust remote("node5.buuoj.cn",28777) addr 0x4006BE payload bA * 0x30 bB*0x8 p64(addr…