Vector/Linux/Vector.hpp

302 lines
7.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
namespace Lenyiin
{
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;
}
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endofstorage - _start;
}
// 默认构造
Vector()
: _start(nullptr), _finish(nullptr), _endofstorage(nullptr)
{
}
// 拷贝构造
// Vector(const Vector<T>& v)
//{
// _start = new T[v.capacity()];
// _finish = _start;
// _endofstorage = _start + v.capacity();
// for (size_t i = 0; i < v.size(); i++)
// {
// *_finish = v[i];
// ++_finish;
// }
//}
// 进阶写法
Vector(const Vector<T> &v)
: _start(nullptr), _finish(nullptr), _endofstorage(nullptr)
{
reserve(v.capacity());
for (const auto &e : v)
{
push_back(e);
}
}
// 赋值运算符重载
// Vector<T>& operator=(const Vector<T>& v)
//{
// if (this != &v)
// {
// delete[] _start;
// _start = new T[v.capacity()];
// //memcpy(_start, v._start, sizeof(T) * v.size()); 按字节拷贝,浅拷贝
// for (size_t i = 0; i < v.size(); i++)
// {
// _start[i] = v._start[i]; // 调用的是 operator= 深拷贝
// }
// _finish = _start + v.size();
// _endofstorage = _start + v.capacity();
// }
// return *this;
//}
// 进阶写法
void swap(Vector<T> &v) // 自己写的swap是浅拷贝代价小
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
Vector<T> &operator=(Vector<T> v)
{
swap(v); // 库里面的swap是深拷贝代价极大
return *this;
}
// 移动构造函数
Vector(Vector &&v) noexcept
: _start(v._start), _finish(v._finish), _endofstorage(v._endofstorage)
{
v._start = nullptr;
v._finish = nullptr;
v._endofstorage = nullptr;
}
// 移动赋值运算符
Vector &operator=(Vector &&v) noexcept
{
if (this != &v)
{
delete[] _start;
_start = v._start;
_finish = v._start + v.size();
_endofstorage = v._start + v.capacity();
v._start = nullptr;
v._finish = nullptr;
v._endofstorage = nullptr;
}
return *this;
}
// 析构函数
~Vector()
{
if (_start)
{
delete[] _start;
}
_start = _finish = _endofstorage = nullptr;
}
// 下标运算符重载
T &operator[](size_t index)
{
if (index >= size())
{
throw std::out_of_range("Index out of range");
}
return _start[index];
}
const T &operator[](size_t index) const
{
if (index >= size())
{
throw std::out_of_range("Index out of range");
}
return _start[index];
}
// 动态扩容
void reserve(size_t newcapacity)
{
if (newcapacity > capacity())
{
T *tmp = new T[newcapacity]; // 分配新内存
size_t len = size();
if (_start)
{
for (size_t i = 0; i < len; i++)
{
tmp[i] = std::move(_start[i]); // 移动已有数据
}
delete[] _start; // 释放旧的内存
}
// 更新指针
_start = tmp;
_finish = tmp + len;
_endofstorage = tmp + newcapacity;
}
}
// resize 不仅会开空间,还会初始化
void resize(size_t newsize, const T &val = T())
{
if (newsize < size())
{
_finish = _start + newsize;
}
else
{
if (newsize > capacity())
{
reserve(newsize);
}
while (_finish < _start + newsize)
{
*_finish = val;
++_finish;
}
}
}
void push_back(const T &data)
{
if (_finish == _endofstorage)
{
size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newcapacity);
}
*_finish = data;
++_finish;
}
// 移动版本
void push_back(T &&data)
{
if (_finish == _endofstorage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
*_finish = std::move(data); // 使用 move 语义
++_finish;
}
// 更安全的访问方式
T &at(size_t index)
{
if (index >= size())
{
throw std::out_of_range("Index out of bounds");
}
return _start[index];
}
void pop_back()
{
assert(_start < _finish);
--_finish;
}
void clear()
{
_finish = _start;
}
iterator insert(iterator pos, const T &data)
{
assert(pos <= _finish);
if (_finish == _endofstorage)
{
size_t len = pos - _start;
size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newcapacity);
// 如果增容原来的pos就失效了这里需要重新计算位置
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = data;
++_finish;
return pos;
}
iterator erase(iterator pos)
{
assert(pos < _finish);
iterator it = pos;
while (it < _finish)
{
*it = *(it + 1);
++it;
}
--_finish;
return pos;
}
private:
iterator _start;
iterator _finish;
iterator _endofstorage;
};
}