一:结构
namespace lxy {
template<class T>
class vector {
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin()const
{
return _start;
}
const_iterator end()const
{
return _finish;
}
private:
iterator _start = nullptr;
iterator _finish = nullptr;
iterator _endofstorage = nullptr;
};
这下明白为啥vector里面可以穿各种类型了吧。
二:一些要用的函数
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos) const
{
assert(pos < size());
return _start[pos];
}
size_t size()const
{
return _finish - _start;
}
size_t capacity()const
{
return _endofstorage - _start;
}
三:reserve
void reserve(size_t n)
{
if (n > capacity())
{
T* tmp = new T[n];
size_t sz = size();
for (int i = 0; i < sz; i++)
{
tmp[i] = _start[i];// 不能memcpy
}
delete[] _start;
_start = tmp;
_finish = _start + sz;
_endofstorage = _start + n;
}
}
注意:这里为啥不能用memcpy?因为会把地址也拷了,这两个指向同一空间了,析构了不就完了
四:插入
void insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
if(_finish=_endofstorage)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4: 2 * capacity());
pos = _start + len;//必须有这步 因为reserve是新空间 pos不改还是老空间
}
int end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
_start[pos] = x;
_finish++;
}//pos前位置插
void push_back(const T& x)
{
insert(end(), x);
}
五:resize
void resize(size_t n, const T& val = T())
{
if (size() > n) _finish=_start + n;
else
{
reserve(n);
while (_finish < _start + n)
{
push_back(val);
_finish++;
}
}
}
六:erase
iterator erase(size_t pos)
{
assert(pos < _finish);
assert(pos >= _start);
iterator it = pos + 1;
while (it < _finish)
{
*(it - 1) = *it;
it++;
}
--_finish;
return pos;
}
注意:为何返回迭代器类型,因为要解决迭代器失效问题。insert erase用了后都会迭代器失效,这里先不多讲喽。
七:构造 析构
vector()
{} //不能不写 因为你写了构造编译器是不会自己生成构造的 无参的你必须自己写 然后private里我们都给过nullptr了
template<class otheriterator >
vector(otheriterator first,otheriterator last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
vector(size_t n, const T& val = T())
{
reserve(n);
for (int i = 0; i < n; i++) push_back(val);
}
vector(int n, const T& val = T())
{
reserve(n);
for (int i = 0; i < n; i++)
{
push_back(val);
}
}//为了匹配
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
vector<T>& operator=(vector<T> tmp)
{
swap(tmp);
return *this;
}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto& e : v)
{
push_back(e);
}
}
~vector()
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
注意匹配那里:为啥有了size_t还要写个int?举个例子,vector<int> v(10,0)构造时,本来想调用size_t,但otheriterator实例化为int发现比size_t更匹配,我们没办法,只能在写一个函数。
八:总体
#pragma once
#include<assert.h>
namespace lxy {
template<class T>
class vector {
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin()const
{
return _start;
}
const_iterator end()const
{
return _finish;
}
vector()
{}
template<class otheriterator >
vector(otheriterator first,otheriterator last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
vector(size_t n, const T& val = T())
{
reserve(n);
for (int i = 0; i < n; i++) push_back(val);
}
vector(int n, const T& val = T())
{
reserve(n);
for (int i = 0; i < n; i++)
{
push_back(val);
}
}//为了匹配
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
vector<T>& operator=(vector<T> tmp)
{
swap(tmp);
return *this;
}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto& e : v)
{
push_back(e);
}
}
~vector()
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
void reserve(size_t n)
{
if (n > capacity())
{
T* tmp = new T[n];
size_t sz = size();
for (int i = 0; i < sz; i++)
{
tmp[i] = _start[i];// 不能memcpy
}
delete[] _start;
_start = tmp;
_finish = _start + sz;
_endofstorage = _start + n;
}
}
void resize(size_t n, const T& val = T())
{
if (size() > n) _finish=_start + n;
else
{
reserve(n);
while (_finish < _start + n)
{
push_back(val);
_finish++;
}
}
}
void insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
if(_finish=_endofstorage)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4: 2 * capacity());
pos = _start + len;//必须有这步 因为reserve是新空间 pos不改还是老空间
}
int end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
_start[pos] = x;
_finish++;
}//pos前位置插
void push_back(const T& x)
{
insert(end(), x);
}
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos) const
{
assert(pos < size());
return _start[pos];
}
size_t size()const
{
return _finish - _start;
}
size_t capacity()const
{
return _endofstorage - _start;
}
iterator erase(size_t pos)
{
assert(pos < _finish);
assert(pos >= _start);
iterator it = pos + 1;
while (it < _finish)
{
*(it - 1) = *it;
it++;
}
--_finish;
return pos;
}
private:
iterator _start = nullptr;
iterator _finish = nullptr;
iterator _endofstorage = nullptr;
};
}