代码
#pragma once
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
namespace zwj
{
template<typename T>
class vector
{
public:
// 迭代器
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator bein() const
{
return _start;
}
const_iterator end() const
{
return _finish;
}
// 默认构造函数
vector()
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{}
vector(size_t n, const T& val = T())
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
if (n > 0)
{
reserve(n);
for (size_t i = 0; i < n; i++)
_start[i] = val;
_finish = _start + n;
_end_of_storage = _start + n;
}
}
// 防止两个int时跳转到迭代器构造函数
vector(int n, const T& val = T())
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
if (n > 0)
{
reserve(n);
for (int i = 0; i < n; i++)
_start[i] = val;
_finish = _start + n;
_end_of_storage = _start + n;
}
}
// 传统写法 —— copy
//vector(const vector<T>& v)
// :_start(nullptr)
// , _finish(nullptr)
// , _end_of_storage(nullptr)
//{
// size_t sz = v.size();
// reserve(sz);
// //memcpy(_start, v._start, sizeof T * sz); // 当存放自定义类型时,还是会发生浅拷贝,只能构造新的对象一个一个插入
// for (size_t i = 0; i < sz; i++)
// _start[i] = v[i];
// _finish = _start + sz;
// _end_of_storage = _start + sz;
//}
// 现代写法 —— copy
vector(const vector<T>& v) // 一定不能使用传值,否则会引发无限递归
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
vector<T> tmp(v.bein(), v.end());
swap(tmp);
}
// 迭代器区间构造
template <class InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
while (first != last)
{
push_back(*first);
first++;
}
}
// 传统写法 —— 赋值
//vector& operator= (const vector& v)
//{
// if (&v != this)
// {
// if (v.size() > size())
// resize(v.size());
// for (size_t i = 0; i < v.size(); i++) // 一个一个插入,防止自定义类型的浅拷贝
// {
// _start[i] = v[i];
// }
// _finish = _start + v.size();
// }
// return *this;
//}
// 现代写法 —— 赋值
vector& operator= (const vector& v)
{
if (this != &v)
{
vector<T> tmp(v);
swap(tmp);
}
return *this;
}
//析构
~vector()
{
delete[] _start;
_start = _finish = _end_of_storage = nullptr;
}
//交换
void swap(vector<T>& v)
{
::swap(_start, v._start);
::swap(_finish, v._finish);
::swap(_end_of_storage, v._end_of_storage);
}
// 任意位置插入(注意迭代器失效)
iterator insert(iterator pos, const T& val)
{
size_t len = pos - _start; // 防止迭代器失效
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : 2 * capacity());
pos = _start + len; // 更新迭代器
}
iterator end = _finish;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = val;
_finish++;
return pos;
}
// 任意位置删除
iterator erase(iterator pos)
{
assert(pos < _finish);
size_t len = pos - _start;
iterator end = pos;
while (end < _finish)
{
*end = *(end + 1);
end++;
}
_finish--;
return _start + len;
}
// resize
void resize(size_t n, T val = T())
{
size_t sz = size();
if (n > sz)
{
if (n > capacity())
{
reserve(n);
}
for (size_t i = sz; i < n; i++)
_start[i] = val;
}
_finish = _start + n;
}
// 扩容
void reserve(size_t n)
{
if (n > capacity())
{
size_t sz = size(); // 防止
T* tmp = new T[n];
//memcpy(tmp, _start, sz * sizeof T); // 当存放自定义类型时,还是会发生浅拷贝,只能构造新的对象一个一个插入
for (size_t i = 0; i < sz; i++)
{
tmp[i] = _start[i];
}
::swap(tmp, _start);
_finish = _start + sz;
_end_of_storage = _start + n;
delete[] tmp;
}
else
{
_finish = _start + n;
}
}
// 尾插
void push_back(const T& val)
{
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : 2 * capacity());
}
*(_finish++) = val;
}
// 尾删
void pop_back()
{
assert(_finish > _start);
_finish--;
}
// 头节点
T& front()
{
assert(_finish > _start);
return *_start;
}
const T& front() const
{
assert(_finish > _start);
return *_start;
}
// 尾结点
T& back()
{
assert(_finish > _start);
return *(_finish - 1);
}
const T& back() const
{
assert(_finish > _start);
return *(_finish - 1);
}
// size
size_t size() const
{
return _finish - _start;
}
// 容量
size_t capacity() const
{
return _end_of_storage - _start;
}
// 下标
T& operator[] (size_t n)
{
assert(n < size());
return _start[n];
}
const T& operator[](size_t n) const
{
assert(n < size());
return _start[n];
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storage;
};
//输出函数
template<typename T>
ostream& operator<<(ostream& out, vector<T> vtr)
{
for (const auto& e : vtr)
out << e << ' ';
//for (size_t i = 0; i < vtr.size(); i++)
// cout << vtr[i] << ' ';
out << endl;
return out;
}
}
注意事项
拷贝问题
不能直接使用memcpy
进行拷贝,当存放自定义类型时还是会发生浅拷贝,需要单独赋值。
构造问题
因为提供了迭代器区间构造,所以使用两个int
进行构造时,会导致构造函数定位到当前迭代器区间构造,所以需要重载一个int
类型的构造函数。
拷贝构造问题
不能使用传值传参,会导致无限递归,只能使用传引用传参
迭代器失效问题
插入时,如果发生扩容会导致迭代器失效变成野指针,需要更新迭代器。
同时使用迭代器进行插入后尽量不要访问迭代器,Windows下插入后继续访问迭代器是会报错的。
删除时,如果发生了缩容,也会导致迭代器失效