【C++初阶】vector的模拟实现

大家好我是沐曦希💕

一、前言

在模拟实现容器时候,我们需要的不是造一个更好的轮子,而是在了解原理更好理解和运用容器。

那么通过查看源码,抽出vector容器主题框架:

template <class T, class Alloc = alloc>
class vector {
   
     typedef T value_type;
     typedef value_type* iterator;
     typedef const value_type* const_iterator;
protected:
    iterator start;
    iterator finish;
    iterator end_of_storage;
}

本质上与T*a,size_t size,size_t capacity是类似的:
在这里插入图片描述
对于size = _finish - _start

在这里插入图片描述

对于capacity = _endofstorage-_start

二、无参构造&析构

  • 无参构造

初始化值为空。

vector()
  :_start(nullptr)
  ,_finish(nullptr)
  ,_endofstarge(nullptr)
{
   }
  • 析构
~vector()
{
   
	delete[] _start;
	_start = _finish = _endofstarge = nullptr;
}

三、基础接口

1.empty和clear

  • empty
bool empty()
{
   
	return _finish == _start;
}
  • clear
void clear()
{
   
	_finish = _start; //这里可不能置为nullptr
}

2.size和capacity

  • size
int size() const
{
   
	return _finish - _start;
}

-capacity

int capacity() const
{
   
	return _endofstarge - _start;
}

加const是让const类对象和非const类对象都能调用

3.[]和iterator

这里提供const和非const两个版本,加const是只可读,不能更改,不加const是可读可写。

  • []
T& operator[](const size_t pos)
{
   
	assert(pos < size());
	return _start[pos];
}
const T& operator[](const size_t pos)
{
   
	assert(pos < size())
		return _start[pos];
}
  • iterator
    同理普通迭代器和const迭代器版本,同理,范围for循环此时也是可以实现的:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
   
	return _start;
}
iterator end()
{
   
	return _finish;
}
const_iterator beign()
{
   
	return _start;
}
const_iterator end()
{
   
	return _finish;
}

四、reserve和resize

  • reserve

reserve最大问题是深拷贝,开辟新空间进行赋值的时候如果直接使用memcpy是浅拷贝。

void reserve(size_t n)
{
   
	if (n > capacity())
	{
   
		int Oldsize = size();//size需要保存,方便更改_finsih
		T* tmp = new T[n];
		//为空不需要拷贝
		if (_start)
		{
   
			for (size_t i = 0; i < Oldsize; ++i)
			{
   
				tmp[i] = _start[i];
			}
		}
		_start = tmp;
		_finish = _start + Oldsize;
		_endofstarge = _start + n;
		tmp = nullptr;
	}
}
  • size()要保存

因为size = _finish - _start,_start已经改变了。而_finish没有改变,那么size就是一个任意数了,不再是原来的size了,就需要在开始时候用Oldsize进行存储size

  • 使用memcpy问题

memcpy拷贝数据是按字节来拷贝的属于浅拷贝,对于需要在堆开辟空间的自定义类型存在问题,多次释放同一块空间将导致程序崩溃

vector<vector<int>> vv;
vector<int> v(4, 1);
//复用push_back尾插
vv.push_back(v);
vv.push_back(v);
vv.push_back(v);
vv.push_back(v);
//需要扩容成2倍
vv.push_back(v);
for (size_t i = 0; i < vv.size(); i++)
{
    
	for (size_t j = 0; j < vv[i].size(); j++)
	{
    
	  cout << vv[i][j] << " ";
	}
	cout << endl;
}

在这里插入图片描述

  • resize

用n个数据初始化vector,那么就要用n和size进行比对,分情况讨论:
1、当n大于当前的size时,将size扩大到n,扩大的数据为val,若val未给出,则默认为容器所存储类型的默认构造函数所构造出来的值。
 2、当n小于当前的size时,将size缩小到n。

根据resize函数的规则,进入函数我们可以先判断所给n是否小于容器当前的size,若小于,则通过改变_finish的指向,直接将容器的size缩小到n即可,否则先判断该容器是否需要增容,然后再将扩大的数据赋值为val即可。

void resize(size_t n, const T& value = T())
{
   
	if (n < size())
	{
   
		_finish = _start + n;
	}
	
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐曦希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值