vector是表示可变大小数组的序列容器
本质其实就是一个动态的顺序表
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
using namespace std;
void test1()
{
vector<int> v1;
vector<int> v2(10, 1);//初始化,10个1
vector<int> v3(v2.begin(), v2.end());//迭代器范围初始化
vector<int> v4(v3);//拷贝构造
string s("hello");
vector<char> v5(s.begin(), s.end());//范围初始化模板可以用string类
}
这里不会把\0拷贝过去
void test2()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);//尾插
v1.pop_back();//尾删
//中间插入/删除
v1.erase(v1.begin() + 2);
v1.insert(v1.end(), 1);
}
注意这里的end
//测试遍历
for (size_t i = 0; i < v1.size(); i++)
{
cout << v1[i];
}
cout << endl;
//迭代器
vector<int>::iterator it = v1.begin();
while (it != v1.end())
{
cout << *it;
it++;
}
cout << endl;
//范围for
for (auto e : v1)
{
cout << e;
}
cout << endl;
测试:
void test3()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);//尾插
v1.reserve(10);
v1.resize(10);
v1.assign(10, 5);//重新分配10个5数值
}
reserve
resize
vector不提供类似string那样的find的功能
std提供了algorithm算法库
void test4()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
vector<int>::iterator ret = find(v1.begin(), v1.end(), 2);
cout << *ret;
}
测试:
优化:
void test4()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
vector<int>::iterator ret = find(v1.begin(), v1.end(), 2);
if (ret != v1.end())//没找到返回end
{
cout << *ret;
}
}
清除数据但不清除空间
v1.clear();
#pragma once
#include
#include
using namespace std;
namespace wyj
{
template<class T>
class vector
{
typedef T* iterator;
typedef const T* const_iterator;
public:
private:
iterator _start;
iterator _finish;
iterator _endofstorage;
};
}
//构造函数
vector()
:_start(nullptr),
_finish(nullptr),
_endofstorage(nullptr)
{}
//析构函数
~vector()
{
//如果是空指针直接进行delete会报错
if (_start)
{
delete[] _start;
_start = _finish = _endofstorage;
}
}
//拷贝构造
vector(const vector<T>& v)
{
_start = new T[v.capacity()];
_finish = _start + v.size();
_endofstorage = _start + v.capacity();
memcpy(_start, v._start, v.capacity());
return *this;
}
优化:
使用自己的构造函数【在string那节有相似的方法
如果要实现,有以下问题,我想使用它自己的构造函数,构造新的vector,然后把成员变量给新的
//这里不能直接写
//vector(T* start)
//{
//}
//因为要计算start的size长度,没有任何具体的方法,数组有数组的方法,字符串有字符串的方法
vector()
:_start(nullptr),
_finish(nullptr),
_endofstorage(nullptr)
{}
vector(const vector<T>& v)
{
//这里如何使用自己的东西去拷贝构造是问题
vector<T> tmp();
}
vector构造函数中有
//构造函数另一个版本,构成函数重载
//这样不仅可以用vector迭代器,还可以用别的类型string的迭代器
//比如vector s1和string s2,可以用s1(s2.begin(), s2.end())
template <class InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr),
_finish(nullptr),
_endofstorage(nullptr)
{
while (first != last)
{
push_back(*first);
first++;
}
}
拷贝构造和operator=
这里为什么不直接使用库函数的swap?
库函数的swap是一个深拷贝,将先创建一个新的vector,然后再相等,最后交换(深拷贝,效率低,我们不需要那么精准的拷贝),我们只需要成员变量的交换
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
//拷贝构造函数
vector(const vector<T>& v)
:_start(nullptr),
_finish(nullptr),
_endofstorage(nullptr)
{
//这里使用类自己的构造函数
vector<T> tmp(v.begin(), v.end());
//这里不能直接相等,因为函数结束tmp会delete,必须把tmp变为nullptr
swap(tmp);
}
vector<T>& operator=(const vector<T> v)//这里直接用拷贝构造函数
{
swap(v);
return *this;
}
测试:
void test3()
{
vector<int> v;
v.push_back(1);
v.push_back(1);
v.push_back(1);
vector<int> v1;
v1 = v;
for (auto e : v1)
{
cout << e;
}
cout << endl;
}
T& operator[](size_t i)
{
assert(i < size());
return _start[i];
}
const_iterator begin()const
{
return _start;
}
const_iterator end()const
{
return _finish;
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endofstorage - _start;
}
//关于扩容
void reserve(size_t n)
{
if (n > capacity())
{
//这里要提前保存,不然size = finish - start 如果start已经变了,再相减就不一样了
size_t ret = size();
T* tmp = new T[n];
//如果是空直接给,不是空拷贝
if (_start != nullptr)
{
memcpy(tmp, _start, sizeof(T) * size());
delete[] _start;
}
_start = tmp;
_finish = _start + ret;
_endofstorage = _start + n;
}
}
void resize(size_t n, const T& val = T())//没给数值默认初始化为T类型的
{
if (n < size())
{
_finish = _start + n;
}
else
{
if (n > capacity())
{
reserve(n);
}
while (_finish != _start + n)
{
*_finish = val;
_finish++;
}
}
}
测试:
//测试resverse
void test2()
{
vector<int> v;
v.push_back(1);
v.push_back(1);
v.push_back(1);
v.reserve(6);
for (auto e : v)
{
cout << e;
}
cout << endl;
v.resize(7);
for (auto e : v)
{
cout << e;
}
cout << endl;
v.resize(2);
for (auto e : v)
{
cout << e;
}
cout << endl;
}
void push_back(const T& x)
{
//相等
if (_finish == _endofstorage)
{
reserve(capacity() == 0 ? 4 : 2 * capacity());
}
*_finish = x;
_finish++;
}
测试
//测试插入和遍历
void test1()
{
vector<int> v;
v.push_back(1);
v.push_back(1);
v.push_back(1);
v.push_back(1);
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i];
}
cout << endl;
}
void insert(iterator pos, const T& x)
{
assert(pos >= _start && pos <= _finish);
//相等
if (_finish == _endofstorage)
{
reserve(capacity() == 0 ? 4 : 2 * capacity());
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = x;
_finish++;
}
测试:
问题:如果扩容之后,pos指向的是释放过的空间,野指针,迭代器失效
修改:
void insert(iterator pos, const T& x)
{
assert(pos >= _start && pos <= _finish);
//相等
if (_finish == _endofstorage)
{
//提前保存距离
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : 2 * capacity());
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = x;
_finish++;
}
iterator erase(iterator pos)
{
assert(pos >= _start && pos < _finish);
while (pos < _finish)
{
*pos = *(pos + 1);
pos++;
}
_finish--;
return pos;
}
测试: