2024年Android最全【C++庖丁解牛】vector容器的简易模拟实现(C,驱动核心源码详解和Binder超系统学习资源

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一起互勉~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


前言

我们前面介绍了vector容器的概念以及对其基本使用进行了介绍,如果你在这里不知道vector是什么以及不知道如何使用的话,可以进入本人主页,在C++专栏里有介绍

为了对小白友好,在这我简单介绍一下

C++中的vector是一个动态数组容器,可以存储不同类型的元素。它提供了一系列的成员函数来方便地操作和管理数组。

以下是C++ vector容器的一些特点和功能:

  1. 动态大小:vector的大小可以根据需要动态调整,可以在运行时添加或删除元素。
  2. 随机访问:可以通过索引直接访问vector中的元素,支持常数时间的随机访问。
  3. 自动内存管理:vector会自动处理内存分配和释放,无需手动管理内存。
  4. 插入和删除:可以在任意位置插入或删除元素,vector会自动调整其他元素的位置。
  5. 迭代器支持:可以使用迭代器遍历vector中的元素。
  6. 动态增长:当vector的容量不足时,会自动重新分配更大的内存空间,以容纳更多的元素。
  7. 元素访问:可以使用下标运算符[]或at()函数来访问元素,也可以使用front()和back()函数分别获取第一个和最后一个元素。

本章节主要对vector容器的手撕实现其简单功能

vector容器代码实现

内部成员简介

命名空间实现与库里vector的隔绝,实现自定义vector

namespace A
{
	template<class T>   //模版实现vector<类型>
	class vector        //vector功能实现
	{
	public:
		// Vector的迭代器是一个原生指针
		typedef T\* iterator;
		typedef const T\* const_iterator;
		.......           //函数接口实现
		.......
	private:
		iterator _start;		// 指向数据块的开始
		iterator _finish;		// 指向有效数据的尾
		iterator _endOfStorage;  // 指向存储容量的尾
	};
}

构造函数

		vector()
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{}

		vector(size_t n, const T& value = T())
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{
			reserve(n);
			while (n--)
			{
				push\_back(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根本不是一个区间,编译时就报错了
	* 故需要增加如下构造方法

vector(int n, const T& value = T())
	: \_start(new T[n])
	, \_finish(_start + n)
	, \_endOfStorage(_finish)
{
	for (int i = 0; i < n; ++i)
	{
		_start[i] = value;
	}
}

拷贝函数

		// 若使用iterator做迭代器,会导致初始化的迭代器区间[first,last)只能是vector的迭代器
		// 重新声明迭代器,迭代器区间[first,last)可以是任意容器的迭代器
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push\_back(\*first);
				++first;
			}
		}

		vector(const vector<T>& v)
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{
			reserve(v.capacity());
			iterator it = begin();
			const_iterator vit = v.cbegin();
			while (vit != v.cend())
			{
				\*it++ = \*vit++;
			}
			_finish = it;
		}

		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return \*this;
		}

析构函数

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


迭代器相关

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator cbegin() const
		{
			return _start;
		}

		const_iterator cend() const
		{
			return _finish;
		}


容量相关

		size_t size() const
		{
			return _finish - _start;
		}

		size_t capacity() const
		{
			return _endOfStorage - _start;
		}

		bool empty() const
		{
			return _start == _finish;
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t oldSize = size();
				// 1. 开辟新空间
				T\* tmp = new T[n];

				// 2. 拷贝元素
				// 这里直接使用memcpy会有问题吗?同学们思考下
				//if (\_start)
				// memcpy(tmp, \_start, sizeof(T)\*size);

				if (_start)
				{
					for (size_t i = 0; i < oldSize; ++i)
						tmp[i] = _start[i];

					// 3. 释放旧空间
					delete[] _start;
				}

				_start = tmp;
				_finish = _start + oldSize;
				_endOfStorage = _start + n;
			}
		}

		void resize(size_t n, const T& value = T())
		{
			// 1.如果n小于当前的size,则数据个数缩小到n
			if (n <= size())
			{
				_finish = _start + n;
				return;
			}

			// 2.空间不够则增容
			if (n > capacity())
				reserve(n);

			// 3.将size扩大到n
			iterator it = _finish;
			_finish = _start + n;
			while (it != _finish)
			{
				\*it = value;
				++it;
			}
		}


元素访问

		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}

		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}

		T& front()
		{
			return \*_start;
		}

		const T& front()const
		{
			return \*_start;
		}

		T& back()
		{
			return \*(_finish - 1);
		}

		const T& back()const
		{
			return \*(_finish - 1);
		}

vector的修改操作

		void push\_back(const T& x)
		{
			insert(end(), x);
		}

		void pop\_back()
		{
			erase(end() - 1);
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endOfStorage, v._endOfStorage);
		}

		iterator insert(iterator pos, const T& x)
		{
			assert(pos <= _finish);

			// 空间不够先进行增容
			if (_finish == _endOfStorage)
			{
				//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;
		}

源代码

#pragma once

#include <iostream>
using namespace std;
#include <assert.h>


namespace A
{
	template<class T>
	class vector
	{
	public:
		// Vector的迭代器是一个原生指针
		typedef T\* iterator;
		typedef const T\* const_iterator;

		///
		// 构造和销毁
		vector()
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{}

		vector(size_t n, const T& value = T())
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{
			reserve(n);
			while (n--)
			{
				push\_back(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根本不是一个区间,编译时就报错了
 \* 故需要增加该构造方法
 \*/
		vector(int n, const T& value = T())
			: \_start(new T[n])
			, \_finish(_start + n)
			, \_endOfStorage(_finish)
		{
			for (int i = 0; i < n; ++i)
			{
				_start[i] = value;
			}
		}

		// 若使用iterator做迭代器,会导致初始化的迭代器区间[first,last)只能是vector的迭代器
		// 重新声明迭代器,迭代器区间[first,last)可以是任意容器的迭代器
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push\_back(\*first);
				++first;
			}
		}

		vector(const vector<T>& v)
			: \_start(nullptr)
			, \_finish(nullptr)
			, \_endOfStorage(nullptr)
		{
			reserve(v.capacity());
			iterator it = begin();
			const_iterator vit = v.cbegin();
			while (vit != v.cend())
			{
				\*it++ = \*vit++;
			}
			_finish = it;
		}

		vector<T>& operator=(vector<T> v)
		{


最后看一下学习需要的所有知识点的思维导图。在刚刚那份学习笔记里包含了下面知识点所有内容!文章里已经展示了部分!如果你正愁这块不知道如何学习或者想提升学习这块知识的学习效率,那么这份学习笔记绝对是你的秘密武器!

![](https://img-blog.csdnimg.cn/img_convert/c7f27563428a62ddf682053dfe4e060e.webp?x-oss-process=image/format,png)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

hile (vit != v.cend())
			{
				\*it++ = \*vit++;
			}
			_finish = it;
		}

		vector<T>& operator=(vector<T> v)
		{


最后看一下学习需要的所有知识点的思维导图。在刚刚那份学习笔记里包含了下面知识点所有内容!文章里已经展示了部分!如果你正愁这块不知道如何学习或者想提升学习这块知识的学习效率,那么这份学习笔记绝对是你的秘密武器!

[外链图片转存中...(img-EUOumlpV-1715625967377)]




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值