vector.h
1、迭代器的实现
#pragma once
#include <assert.h>
namespace JPC
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
//迭代器的实现
//普通迭代器
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
//const迭代器
const iterator begin()const
{
return _start;
}
const iterator end()const
{
return _finish;
}
2、构造函数与析构函数
//构造函数
vector()
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{}
//析构函数
~vector()
{
delete[] _start;
_start = _finish = _end_of_storage = nullptr;
}
3、求出 capacity \ size 以及实现 operator[ ]
//求出 capacity
size_t capacity()const
{
return _end_of_storage - _start;
}
//求出 size
size_t size()const
{
return _finish - _start;
}
//实现:[]
T& operator[](size_t pos)
{
assert(pos<size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
}
4 、预先开辟空间
//预先开辟空间
void reserve(size_t n)
{
size_t sz = size();//预先保留 size() 的大小,因为一旦delete过后,size() 就变为0了
if (n>capacity())
{
T* tmp = new T[n];
if (_start) //如果原来的数组不为空,就把数据拷贝到tmp空间中
{
memcpy(tmp,_start,sizeof(T)*size());
delete[] _start;
}
//确定新空间的 _start \ _finish \ _end_of_storage
_start = tmp;
_finish = _start + sz;
_end_of_storage = _start + n;
}
}
5、尾插、尾删
//尾插
void push_back(const T& x) //用引用传参,如果T是自定义类型的,就不需要拷贝构造(深拷贝),减少消耗
{
检测是否需要扩容
//if (_finish==_end_of_storage)
//{
// reserve(capacity()==0 ? 4:capacity()*2);
//}
//*_finish = x;
//++_finish;
insert(end(),x);
}
//尾删
void pop_back()
{
//防止删除到越界了
assert(_finish>_start);
--_finish;
}
6、任意位置插入、删除
//插入
void insert(iterator pos,const T& x)
{
assert(pos>=_start && pos<=_finish);
//检测是否需要扩容
if (_finish==_end_of_storage)
{
//在扩容前需要记录好pos的位置
size_t len = pos - _start;
reserve(capacity()==0 ? 4:capacity()*2);
//扩容后需要重新确定pos的位置
pos = _start + len;
}
//挪动数据
iterator end = _finish - 1;
while (end>=pos)
{
*(end+1) = *end;
--end;
}
//插入数据
*pos = x;
++_finish;
}
//删除
//stl 规定 vector::erase 返回删除位置的下一个位置的迭代器(地址)
iterator erase(iterator pos)
{
assert(pos>=_start && pos<_finish);
iterator begin = pos;
while (begin<_finish-1)
{
*begin = *(begin+1);
++begin;
}
--_finish;
return pos;
}
private:
iterator _start; //_start为vector存储的首个数据的地址(指针)
iterator _finish; //_finish为存储的末尾数据的下一个数据的地址
iterator _end_of_storage; //_end_of_storage为vector内开辟的最后一个空间的下一个空间的地址
};
7、test_vector
void test_vector1()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for (size_t i=0;i<v.size();++i)
{
cout<< v[i] <<" ";
}
cout << endl;
vector<int>::iterator it = v.begin();
while (it != v.end())
{
cout<< *it <<" ";
++it; //切莫忘记了
}
cout << endl;
//范围for ( 底层是迭代器,傻瓜式的替换 v.begin() 和 v.end() )
for (auto e:v)
{
cout<< e <<" ";
}
cout << endl;
v.pop_back();
v.pop_back();
for (size_t i=0;i<v.size();++i)
{
cout<< v[i] <<" ";
}
cout << endl;
}
void Func(const vector<int>& v)
{
vector<int>::const_iterator it = v.begin();
while (it != v.end())
{
//++*it; //无法改变 *it 的值
cout<< *it <<" ";
++it;
}
cout << endl;
}
void test_vector()
{
//测试 insert 和 erase
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for (size_t i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
v.insert(v.end(), 6);
for (size_t i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
v.erase(v.end() - 1);
for (size_t i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
v.erase(v.begin());
for (size_t i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
}
void test_vector2()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (auto e:v)
{
cout<< e <<" ";
}
cout << endl;
auto p = find(v.begin(),v.end(),3); //支持了迭代器,就支持了stl里面的find
if (p != v.end())
{
v.insert(p,30); //当需要在pos位置插入数据时,遇到了vector需要扩容的情况;注意在扩容之后,pos已经失效了(因为pos是指向原来数组中的某个位置,现在数组直接销毁了)
}
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}
void test_vector3()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for (auto e:v)
{
cout<< e <<" ";
}
cout << endl;
auto p = find(v.begin(),v.end(),3);
if (p != v.end())
{
v.erase(p);
}
for (auto e:v)
{
cout<< e <<" ";
}
cout << endl;
}
void test_vector4()
{
//情况1:运行正常——运气好
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
//要求删除所有的偶数
auto it = v.begin();
while (it != v.end())
{
//没有更新迭代器的代码是:
/*if (*it % 2==0)
{
v.erase(it);
}
++it;*/
//有迭代器更新的代码:
if (*it % 2 == 0)
{
it = v.erase(it); //要更新迭代器,也就是pos的位置
}
else
{
++it;
}
}
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}
//结论: insert/erase pos位置,不要直接访问pos。一定要更新,直接访问可能会导致各种出乎意料的结果,这就是所谓的迭代器失效。
//【要认为pos失效了,不要访问】
}
Test.cpp
#include <iostream>
using namespace std;
#include "vector.h"
int main()
{
JPC::test_vector4();
return 0;
}