根据小编之前讲解的vector容器,我们都知道了容器vector的底层实现原理是一维数组,也就是说在定义一个vector容器的时候,默认构造函数就已经给容器一个默认的容量了,然后在我们的开发中使用的push_back(val)添加元素,一旦发现容器的容量不足,那么就会触发容器的扩容机制,扩容机制的流程是:
先申请内存——将原本的容量变成原来的n倍——将原本容器中的数据拷贝到新的容器中——释放原来的空间——将数组指针指向新的容器空间
现在让我们徒手来实现一下vector容器:
#ifndef _VECTOR_H_
#define _VECTOR_H_
#include <iostream>
using namespace std;
// 创建模板类
#define VECTOR_BASE_SIZE 5 // 默认基础容量
#define INC_BASE 2 // 默认扩容倍数
template <class T>
class Vector {
public:
// 常见的vector构造函数
Vector()
: _cap(VECTOR_BASE_SIZE), _size(0)
{
_arr = new T[VECTOR_BASE_SIZE];
}
Vector(int cap)
: _cap(cap), _size(0)
{
_arr = new T[cap];
}
Vector(int cap, T e)
: _cap(cap), _size(0)
{
_arr = new T[cap];
for (int i = 0; i < cap; i++)
_arr[i] = e;
}
~Vector()
{
if (_arr) {
delete[] _arr;
_arr = nullptr;
}
_cap = 0;
_size = 0;
}
// 向尾部插入元素
void push_back(T e)
{
// 先要判断当前的存储数量是不是已经到达容器容量
if (_cap == _size) // 已经到达最大容量了,需要进行扩容
{
// 开辟一块新的内存,原来的元素拷贝过去
T *new_arr = new T[_cap * 2];
for (int i = 0; i < _cap; i++)
new_arr[i] = _arr[i];
// 释放原来那块内存,重新指向
delete[] _arr;
_arr = new_arr;
_cap *= 2;
}
// 插入最后
_arr[_size++] = e;
}
// 删除尾部元素
void pop_back()
{
if (_size) // 有元素,让下标减1
_size--;
}
// 获取尾部元素
T back()
{
if (_size)
return _arr[_size - 1];
}
// 获取头部元素
T front()
{
if (_size)
return _arr[0];
}
// 重载下标运算符
T operator [](int idx)
{
if (idx >= _size || idx < 0) // 非法下标,不允许访问,返回相关出错信息
{
cout << "This index invalid.Return arguement idx." << endl;
return idx;
}
return _arr[idx];
}
// 获取容量和已存储数量
int size() const
{
return _size;
}
int capacity() const
{
return _cap;
}
private:
T* _arr;
int _cap;
int _size;
};
#endif // !_VECTOR_H_
int main()
{
Vector<int> vec;
for (int i = 0; i < 10; i++) {
vec.push_back(i+1);
cout << "capacity: " << vec.capacity() << " size: " << vec.size() << endl;
}
cout << "idx: 5 element: " << vec[5] << endl;
return 0;
}