【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库看看。
#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中Vector
- 模拟实现STL中的vector
- 【STL】模拟实现vector
- 【STL】vector的模拟实现
- STL中vector的使用以及模拟实现
- STL-模拟实现vector(含类型萃取)
- 模拟实现STL-Vector
- STL模拟实现vector
- 模拟实现STL中的Vector容器
- STL vector的模拟实现
- 【STL】之Vector的模拟实现
- STL库中的vector的使用和模拟实现
- 关于C++中STL中vector实现的几道考试题
- [置顶] 从零开始学C++之对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr<class>、实现Ptr_vector
- 链式前向星|前向星|STL中vector模拟链表(图的存储)
- [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)
- [置顶] 从零开始学C++之STL(二):实现简单容器模板类Vec(vector capacity 增长问题、allocator 内存分配器)
- C++面试题:介绍一下STL,STL如何实现vector
- stl容器区别: vector list deque set map-底层实现
- stl容器区别: vector list deque set map-底层实现