您的位置:首页 > 编程语言 > C语言/C++

【STL】 vector 模拟实现

2016-09-23 19:55 471 查看
    上一篇博客说了一下list的使用,其实vector用法基本上和list是一样的,所以此篇博客就只模拟实现以下vector。vector你可以把它理解成一个顺序表或者数组。只是STL里的vector是由三个迭代器来维护的:_start(数据存放开始的位置),_finish(数据存放结束位置的下一个),_endofstorage(容量的最后一个位置)。vector里的迭代器其实就是个指针。来看看代码实现:

#include<iostream>
#include<vector>
using namespace std;

template<class T>
class MyVector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;

MyVector(size_t n=3) //构造函数,初始化给3个T类型容量
:_start(new T
), _finish(_start), _end_of_storage(_start+n)
{
}
MyVector(const MyVector<T>& v) //拷贝构造
{
if (v._finish - v._start > _finish - _start)
{
delete[] _start;
_start = new T[v._finish - v._start];
_finish = _start;
}
for (Iterator tmp = v._start; tmp != v._finish; tmp++)
{
*(_finish) = *tmp;
_finish++;
}
_end_of_storage = _finish;
}
void PushBack(const T& x) //尾插,这里注意,即使调用的insert里检查了容量,尾插函数仍需检测
{
CheckCapacity();
Insert(End(), x);
}
void PopBack()
{
Iterator pos = End(); //前置的--因为返回的是临时变量的值,所以不能直接对End()函数进行--
Erase(--pos);
}

void Insert(Iterator pos, const T& x)
{
CheckCapacity();
for (Iterator tmp = End(); tmp != pos;tmp--)
{
*tmp = *(tmp - 1);
}
*pos = x;
_finish++;
}

void Erase(Iterator pos)
{
Iterator end = End();
for (Iterator tmp = pos; tmp != (--end); tmp++)
{
*tmp = *(tmp + 1);
}
_finish--;
}

size_t Size()
{
return _finish - _start;
}
/************迭代器部分***********/
Iterator Begin()
{
return _start;
}
Iterator End()
{
return _finish;
}
/*Iterator operator++(int)
{
Iterator tmp = *this;
tmp++;
return tmp;
}
Iterator& operator++()
{
Iterator tmp = *this;
tmp++;
return *this;
}
Iterator operator--(int)
{
Iterator tmp = *this;
tmp--;
return tmp;
}
Iterator& operator--()
{
Iterator tmp = *this;
tmp--;
return *this;
}
*/
private:
void CheckCapacity()
{
if (_finish == _end_of_storage)
{
Iterator new_start = new T[2 * Size()]; //一次扩容原来的两倍
Iterator new_finish = new_start;
for (Iterator i = Begin(); i != End(); i++,new_finish++)
{
*new_finish = *i;
}
delete[] _start;
_start = new_start;
_finish = new_finish;
_end_of_storage = _start + 2 * Size();
}
}
private:
Iterator _start;
Iterator _finish;
Iterator _end_of_storage;
};

void TestVector()
{
MyVector<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4);
MyVector<int>::Iterator it;
for (it = v.Begin(); it != v.End(); it++)
{
cout << *it << " ";
}
cout << endl;
v.PopBack();
v.PopBack();
for (it = v.Begin(); it != v.End(); it++)
{
cout << *it << " ";
}
cout << endl;
MyVector<int> v1(v);
for (it = v1.Begin(); it != v1.End(); it++)
{
cout << *it << " ";
}
cout << endl;
}

写vector时,犯了好多愚蠢的错误:

1.因为pushpack()函数是调用Insert()函数实现的,而Insert()函数内部有检测容量,所以刚开始Pushpack()就没有检测,程序崩溃了。因为在Insert里扩容时,等于说重新开辟了一块更大的内存,那你Pushback传过来的End()位置将永远也找不到,因为那块内存已经被释放了。

2.其实这里的迭代器它就是一个指针,根本没必要再对它的++,--,什么的进行重载,我好像是陷入了list的迷阵中无法自拔-_-....

    为什么会这么凌乱呢,因为写vector时,我边看《老九门》边敲代码。。。回头再看看真是。。。所以,作为程序员,该敲代码时还是老老实实敲吧。。。

    我这里在拷贝构造时,只开辟了有效值个数,考虑到实际中拷贝后应该不会再插入,所以这样做也是一种省空间的做法。

    vector包含的函数当然不止这些,有兴趣可以查阅STL库看看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl list 模拟实现 C++