1. 模拟实现
由于实现的是一个类模板,那么可以先写处以下代码
namespace cx
{
template<class T>
class vector
{
private:
}
}
1.1 成员变量
vector的成员变量为三个指针。含义如下
start; //指向开始
finish; //指向最后数据的下一个
end_of_storage; //指向最大容量的后一个位置
指针指向的数据类型为T,因此指针的类型为T*
在内部可以加入一条typedef,这也是迭代器的需要。
typedef T* iterator;
这样我们的代码就成了这样
namespace cx
{
template<class T>
class vector
{
public:
typedef T* iterator;
private:
iterator start; //指向开始
iterator finish; //指向最后数据的下一个
iterator end_of_storage; //指向最大容量的后一个位置
};
}
接下来就实现成员函数。
1.2 成员函数
构造函数
只需要将三个指针初始化为nullptr即可
vector()
:start(nullptr)
,finish(nullptr)
,end_of_storage(nullptr)
{}
插入和删除
当空间不够时(finish==end_of_storage),需要扩容。
而insert时,扩容会导致迭代器失效。
所以在insert扩容时,需要保留一下pos和start的距离。
而erase时,如果删除pos位置的数据,那么也认为迭代器失效了。
void reserve(size_t capacity)
{
if (this->capacity() < capacity)
{
size_t old_size = this->size();
T* tmp = new T[capacity];
//memcpy(tmp, this->start,sizeof(T)*old_size); //本质浅拷贝,会导致堆空间多次析构
for (size_t i = 0; i < old_size; ++i)
{
tmp[i] = this->start[i];
}
delete[] this->start;
this->start = tmp;
this->finish = tmp + old_size;
this->end_of_storage = tmp + capacity;
}
}
void resize(size_t size)
{
finish = start;
finish += size;
}
//尾插,尾删
void push_back(const T& val)
{
if (this->finish == this->end_of_storage)
{
size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
reserve(new_capacity);
}
*this->finish = val;
this->finish++;
}
void pop_back()
{
assert(size() > 0);
--finish;
}
//pos位置插入和删除
iterator insert(iterator pos, const T& val)
{
assert(pos >= start);
assert(pos <= finish);
if (finish == end_of_storage)
{
//扩容会导致迭代器失效
size_t leng = pos - this->start;
size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
reserve(new_capacity);
pos = this->start + leng;
}
iterator end = finish;
while (end > pos)
{
*end = *(end-1);
--end;
}
*pos = val;
++finish;
return pos;
}
//删除后,认为迭代器失效
iterator erase(iterator pos)
{
assert(pos >= start);
assert(pos < finish);
iterator begin = pos + 1;
while (begin < finish)
{
*(begin - 1) = *begin;
++begin;
}
--finish;
return pos;
}
其他
//num个val值初始化
vector(size_t num, const T& val = T())
{
reserve(num);
for (size_t i = 0; i < num; ++i)
{
push_back(val);
}
}
vector(int num, const T& val = T())
{
reserve(num);
for (int i = 0; i < num; ++i)
{
push_back(val);
}
}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto e : v)
{
push_back(e);
}
}
//析构函数
~vector()
{
delete[] start;
start = finish = end_of_storage = nullptr;
}
// [ ] 重载
const T& operator[](size_t pos) const
{
return start[pos];
}
T& operator[](size_t pos)
{
return start[pos];
}
bool empty() const
{
return size() == 0;
}
//大小和容量
size_t size() const
{
return finish - start;
}
size_t capacity() const
{
return end_of_storage - start;
}
//交换
void swap(vector<T>& v)
{
std::swap(this->start, v.start);
std::swap(this->finish, v.finish);
std::swap(this->end_of_storage, v.end_of_storage);
}
//赋值重载
vector<T>& operator= (const vector<T>& v)
{
reserve(v.capacity());
for (size_t i = 0; i < v.size(); ++i)
{
start[i] = v[i];
}
finish = start;
finish += v.size();
end_of_storage = start;
end_of_storage += v.capacity();
return *this;
}
1.3 迭代器
迭代器。也是一个类,成员变量大多数情况是一个指针。通过对++,-- ,*,->,==,!=等运算符重载,使得遍历数据时,有一个统一的方法。它不关注容器底层的实现细节和结构。
这也是封装的体现。
template<class Iterator,class ptr,class ref>
class Reverse_Iterator
{
public:
typedef Reverse_Iterator<Iterator,ptr,ref> self;
Reverse_Iterator(Iterator it)
:_it(it)
{}
self& operator++()
{
_it--;
return *this;
}
self operator++(int)
{
self tmp(_it);
_it--;
return tmp;
}
ref operator*()
{
return *_it;
}
ptr operator->()
{
return &(*_it);
}
bool operator!=(const self& rit)
{
return _it != rit._it;
}
private:
Iterator _it;
};
而const迭代器,不允许修改数据,它和普通迭代器的差别只有重载*和->的返回值。因此增加两个模板参数,通过传不同的类型,实现出不同的类。
在vector类内,将迭代器添加进去即可,最终代码如下。
#pragma once
#include<assert.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
using namespace std;
namespace cx
{
template<class Iterator,class ptr,class ref>
class Reverse_Iterator
{
public:
typedef Reverse_Iterator<Iterator,ptr,ref> self;
Reverse_Iterator(Iterator it)
:_it(it)
{}
self& operator++()
{
_it--;
return *this;
}
self operator++(int)
{
self tmp(_it);
_it--;
return tmp;
}
ref operator*()
{
return *_it;
}
ptr operator->()
{
return &(*_it);
}
bool operator!=(const self& rit)
{
return _it != rit._it;
}
private:
Iterator _it;
};
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
typedef Reverse_Iterator<iterator,T*,T&> reverse_iterator;
typedef Reverse_Iterator<const_iterator,const T*,const T&> const_reverse_iterator;
//迭代器
iterator begin()
{
return start;
}
iterator end()
{
return finish;
}
const_iterator begin() const
{
return start;
}
const_iterator end() const
{
return finish;
}
reverse_iterator rbegin()
{
return reverse_iterator(end() - 1);
}
reverse_iterator rend()
{
return reverse_iterator(begin() - 1);
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end() - 1);
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin() - 1);
}
//默认构造
vector()
:start(nullptr)
,finish(nullptr)
,end_of_storage(nullptr)
{}
//num个val值初始化
vector(size_t num, const T& val = T())
{
reserve(num);
for (size_t i = 0; i < num; ++i)
{
push_back(val);
}
}
vector(int num, const T& val = T())
{
reserve(num);
for (int i = 0; i < num; ++i)
{
push_back(val);
}
}
//迭代器区间初始化
template<class input_iteartor>
vector(input_iteartor first, input_iteartor last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
vector(initializer_list<T> list)
{
reserve(list.size());
for (auto e : list)
{
push_back(e);
}
}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto e : v)
{
push_back(e);
}
}
//析构函数
~vector()
{
delete[] start;
start = finish = end_of_storage = nullptr;
}
// [ ] 重载
const T& operator[](size_t pos) const
{
return start[pos];
}
T& operator[](size_t pos)
{
return start[pos];
}
bool empty() const
{
return size() == 0;
}
//大小和容量
size_t size() const
{
return finish - start;
}
size_t capacity() const
{
return end_of_storage - start;
}
void reserve(size_t capacity)
{
if (this->capacity() < capacity)
{
size_t old_size = this->size();
T* tmp = new T[capacity];
//memcpy(tmp, this->start,sizeof(T)*old_size); //本质浅拷贝,会导致堆空间多次析构
for (size_t i = 0; i < old_size; ++i)
{
tmp[i] = this->start[i];
}
delete[] this->start;
this->start = tmp;
this->finish = tmp + old_size;
this->end_of_storage = tmp + capacity;
}
}
void resize(size_t size)
{
finish = start;
finish += size;
}
//尾插,尾删
void push_back(const T& val)
{
if (this->finish == this->end_of_storage)
{
size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
reserve(new_capacity);
}
*this->finish = val;
this->finish++;
}
void pop_back()
{
assert(size() > 0);
--finish;
}
//pos位置插入和删除
iterator insert(iterator pos, const T& val)
{
assert(pos >= start);
assert(pos <= finish);
if (finish == end_of_storage)
{
//扩容会导致迭代器失效
size_t leng = pos - this->start;
size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
reserve(new_capacity);
pos = this->start + leng;
}
iterator end = finish;
while (end > pos)
{
*end = *(end-1);
--end;
}
*pos = val;
++finish;
return pos;
}
//删除后,认为迭代器失效
iterator erase(iterator pos)
{
assert(pos >= start);
assert(pos < finish);
iterator begin = pos + 1;
while (begin < finish)
{
*(begin - 1) = *begin;
++begin;
}
--finish;
return pos;
}
//交换
void swap(vector<T>& v)
{
std::swap(this->start, v.start);
std::swap(this->finish, v.finish);
std::swap(this->end_of_storage, v.end_of_storage);
}
//赋值重载
vector<T>& operator= (const vector<T>& v)
{
reserve(v.capacity());
for (size_t i = 0; i < v.size(); ++i)
{
start[i] = v[i];
}
finish = start;
finish += v.size();
end_of_storage = start;
end_of_storage += v.capacity();
return *this;
}
private:
iterator start; //指向开始
iterator finish; //指向最后数据的下一个
iterator end_of_storage; //指向最大容量的后一个位置
};
}