目录
一、vector的使用格式
vector<类型> 变量名
vector可以看成一个数组,类型决定了这个数组是什么类型。
如vector<int> a 就是整形数组,vector<char> b 就是字符串数组……
但也有特殊的类型,如,vector<string> c 也就是成为string数组,vector<vector<int>> d 基本跟二维数组一样。
二、vector的模拟实现代码
三、vector的结构
我们要模拟实现string,首先我们要知道它的基本结构,它是由_start指针,_finish指针和_endOfStarage指针组成,_start作为起始地址,_finsih用判断存储内容的长度,_endOfStarage用于判断vectro是否要扩容。
即vector的初始结构是这样。
template<class T>
class vector
{
public:
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
private:
iterator _start = nullptr; // 指向数据块的开始
iterator _finish = nullptr; // 指向有效数据的尾
iterator _endOfStorage = nullptr; // 指向存储容量的尾
};
而指针的类型是由你定义的类型所决定的。
四、vector的模拟实现
1、string的构造
其中构造必然避不开开辟空间。
size_t capacity() const
{
return _endOfStorage - _start;//用末地址减初地址就可以得到开辟的空间
}
void reserve(size_t n)
{
if (n > capacity())
{
T* tmp = new T [n];
size_t _size = size();
for (int i = 0; i < (int)size(); i++)
{
tmp[i] = _start[i];
}
_start = tmp;
_finish = tmp + _size;
_endOfStorage = tmp + n;
}
}
(下面以vector<int>为例)
int main()
{
vector<int> a(10,0);//在a中存放十个零
vector<int> b(a);
vector<int> c;
c = a;
return 0;
}
C++中可以用上面三种方法初始化或赋值一个vector<int>类型的变量。
下面四个函数分别对应着上面的初始化或赋值。
vector(int n, const T& value = T())
{
reserve(n);
for (int i = 0; i < n; i++)
{
push_back(value);
}
}
vector(const vector<T>& v)
{
reserve(v.size());
for (auto& e : v)
{
push_back(e);
}
}
vector()
{}
vector<T>& operator= (vector<T> v)
{
if (_start != v._start)
{
vector<T> tmp(v);
swap(tmp);
}
return *this;
}
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endOfStorage, v._endOfStorage);
}
2、vector的插入
vector的插入方式:中间插入和尾插。
void push_back(const T& x)
{
if (_finish == _endOfStorage)
{
reserve(_endOfStorage == nullptr ? 4 : capacity() * 2);
}
*_finish = x;
_finish++;
}
iterator insert(iterator pos, const T& x)
{
if (_finish == _endOfStorage)
{
size_t len = pos - _start;
reserve(_endOfStorage == nullptr ? 4 : capacity() * 2);
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = x;
_finish++;
return pos;
}
pos是我们要插入的位置,c是插入的字符,每次插入都要判断一下插入位置是否合理和是否要扩容,然后就开始进行挪位。
3、vector的删除
iterator erase(iterator pos)
{
assert(pos < _finish);
assert(pos >= _start);
iterator _begin = pos + 1;
while (_begin != _finish)
{
*(_begin - 1) = *_begin;
_begin++;
}
_finish--;
return pos;
}
pos是我们要删除的位置,每次删除要确保在vector的范围,然后从后往前挪数据。
4、vector下标[]的重载
vector可以使用下标来访问和修改数据,所以模拟实现vector,我们要重载[]。
T& operator[](size_t pos)
{
assert(pos < size());
assert(pos >= 0);
return *(_start + pos);
}
const T& operator[](size_t pos)const
{
assert(pos < size());
assert(pos >= 0);
return *(_start + pos);
}