模拟实现了vector的常见构造,插入,删除erase(),预留空间reverse(),重调大小resize()等操作;
具体看代码,有注释。
这里在实现vector这个类时,由于vector是连续的一段空间,利用指针对其管理,迭代器即为其自身类型的指针,因此迭代器不需要重载++,–,*等操作。
常用接口:
实现:
#include <stdio.h>
#include <iostream>
#include<string.h>
using namespace std;
namespace xxx {
template<typename _Ty>
class vector
{
public:
typedef _Ty* iterator; //指针充当迭代器
vector():_first(nullptr),_last(nullptr),_end(nullptr)
{}
vector(int n, const _Ty& value ):_first(nullptr), _last(nullptr), _end(nullptr) //n个value的初始化
{
reverse(n);
while (n--) {
push_back(value);
}
}
vector(iterator first, iterator last) { //根据迭代器区间创建
iterator p = first;
size_t n = last - first;
reverse(n);
while (n--) {
push_back(*p);
p++;
}
}
vector(vector<_Ty> &v) :_first(nullptr), _last(nullptr), _end(nullptr) //根据vector构造
{
reverse(v.size());
iterator p = v.begin();
iterator it = begin();
while (p != v.end()) {
*it = *p;
it++;
p++;
}
_last = _first + v.size();
}
~vector() {
delete[] _first;
_first = _end = _last = nullptr;
}
public:
_Ty& operator[](size_t pos) {
return *(_first + pos);
}
iterator begin()
{
return _first;
}
iterator end()
{
return _last;
}
_Ty front(){
return *_first;
}
_Ty back() {
return *(--_last);
}
void push_back(const _Ty & x) {
insert(end(), x);
}
void push_front(const _Ty& x) {
insert(begin(), x);
}
void reverse(size_t n) { //预留空间,需要跟现有容量比较;
if (n > capacity()) {//扩容
size_t old_size = size();
_Ty* new_first = new _Ty[n]();
memcpy(new_first, _first, sizeof(_Ty) * old_size);
delete[] _first; //拷贝后删除原空间
_first = new_first;
_last = _first + old_size;
_end = _first + n;
}
}
iterator insert(iterator _P, const _Ty& x) {
if (_last == _end) {//如果容量不够则扩容;
/*size_t p_size = _P - _first; //无reverse()方法实现
size_t old_size = capacity();
size_t new_size = old_size==0 ? 1:old_size* 2;
_Ty* new_first = new _Ty[new_size];
memcpy(new_first, _first, sizeof(_Ty) * old_size);
delete[] _first;
_first = new_first;
_last = _first + old_size;
_end = _first + new_size;*/
/
size_t p_size = _P-_first;
size_t new_size = (size()== 0 ? 1 : 2 * size());
reverse(new_size);
_P = _first + p_size;
}
iterator end = _last;
while (end > _P) {
*end = *(end - 1);
--end;
}
*_P = x;
++_last;
return _P;
}
void swap(vector<_Ty> &v) { //交换两VECTOR
iterator tmp1=_first, tmp2=_last, tmp3=_end;
_first = v._first, _last = v._last, _end = v._end;
v._first = tmp1, v._last = tmp2, v._end = tmp3;
}
void resize(size_t n, const _Ty& value=_Ty()) { //重新调整大小,可设置值,无则默认用0初始化
if (n <= capacity()) {
_last = _first + n;
return;
}
else {
reverse(n);
while (_last != _end) {
*_last = value;
_last++;
}
}
}
iterator& erase(iterator _P) { //删除一个迭代器元素
iterator cur = _P;
while (_P < _last) {
*_P = *(_P+1);
_P++;
}
_last--;
return _P;
}
size_t capacity()const
{
return _end - _first;
}
size_t size()const {
return _last-_first;
}
bool empty() {
return size() == 0;
}
private:
iterator _first; //头元素
iterator _last; //尾元素 size = _last -_first
iterator _end; //总空间尾部 capcaity = _end - _first
};
};
测试:
int main()
{
int a[] = { 2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10 };
xxx::vector<int> v1(&a[3],&a[10]);//根据迭代器区间创建
xxx::vector<int> v2(v1);
v2.push_back(999);
v2.swap(v1); //交换两个Vector
v2.resize(20); //重调大小
v2.push_front(9999); //头插
cout << "v2size:" << v2.size() << " v2capacity:" << v2.capacity() << endl;
xxx::vector<int>::iterator x = find(v2.begin(), v2.end(), 9999); //find()为系统自带的全局的查找函数
v2.erase(x); //移除iterator元素
cout << "v2size:" << v2.size() << " v2capacity:" << v2.capacity() << endl;
cout << "v1size:" << v1.size() << " v1capacity:" << v1.capacity() << endl;
for (int i = 0; i < v1.size(); i++) { //按[]访问
cout << v1[i] << " ";
}
cout << endl;
for (auto& x : v2) {
cout << x << " ";
}
//xxx::vector<int> v;
//v.push_back(4);
//v.push_back(5);
//v.push_back(6);
//auto pos = v.begin();
//pos = v.insert(pos, 3);
//pos = v.insert(pos, 2);
//pos = v.insert(pos, 1);
//v.push_front(99);
//v.push_front(100);
//v.reverse(50);
//cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
//cout << v.size() << " " << v.capacity() << " " << *v.begin() << " " << * v.end() << " " << v.empty()<< endl;
//cout << " " << v.back() << " " << v.front()<<endl;
return 0;
}
vector 迭代器失效问题
迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T*。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。
对于vector可能会导致其迭代器失效的操作有:
- 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize(空间不够时,重新开辟一块空间拷贝原数据,原来的空间销毁,迭代器失效)、reserve、insert、assign、push_back等。
- 删除操作–erase
erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。解决办法:erase会返回下一个迭代器位置,在使用前对迭代器重新赋值即可。