此处标明:以下成员函数都是写在my_list类内部的
#include<iostream>
#include<assert.h>using namespace std;template<class T>
class my_vector
{
public://构造函数//赋值运算符重载//析构函数//迭代器typedef T* iterator;typedef const T* const_iterator;//Capacity//element access//modifyprivate:iterator _start; //首元素地址iterator _finish; //最后一个元素下一个位置地址iterator _end_of_storage; //空间尾地址
};
1、无参构造
my_vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}
2、n个value构造
my_vector(size_t n, const T& val = T()){//开空间_start = new T[n];//赋值size_t i = 0;while (i < n){_start[i] = val;i++;}_finish = _end_of_storage = _start + n;}
3、迭代器构造
因为这里的迭代器是一个泛型的迭代器,有可能迭代器内部没有实现减法的功能,所以这里就通过迭代器遍历然后尾插的操作来实现迭代器构造
template<class InputIterator>my_vector(InputIterator first, InputIterator last){//first和last都是泛型迭代器,并不一定支持相减的操作,所以用迭代器遍历尾插操作构造_start = new T;while (first != last){push_back(first);first++;}}
构造实例:
void test(){int arr[5] = {1, 2, 3, 4, 5};my_vector<int> v(arr, arr + 5);}
my_vector(const my_vector<T>& v){size_t sz = v.size();size_t cap = v.capacity();//开空间T* tmp = new T[cap];//深拷贝size_t i = 0;while (i < sz){tmp[i] = v[i];i++;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + v.capacity();}
在将拷贝对象的内容拷贝到构造对象时,因为对象类型可能是自定义类型,所以不能使用memcpy来进行浅拷贝,而是要用循环赋值的方式进行深拷贝;
my_vector<T>& operator=(my_vector<T> v){Swap(v);return *this;}
首先在接收参数时发生了一次拷贝构造,再将形参与对象本身进行交换,完成了一次深拷贝,函数结束时调用析构将形参析构,这样就完成了一次赋值;
~my_vector(){if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}}
//迭代器typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator cbeign() const{return _start;}const_iterator cend() const{return _finish;}
1、获取有效元素个数size
因为 _finish 指向最后一个元素的下一个位置,_start指向首元素位置,所以两个的差值就是有效元素个数;
size_t size() const{return _finish - _start;}
2、获取最大有效元素容量capacity
同理,_end_of_storage指向空间末尾位置,所以与 _start 的差值就是空间的容量;
size_t capacity() const{return _end_of_storage - _start;}
3、增加空间总容量reserve
在增容时,先判断新增的容量是否大于原有空间的容量,如果小于,则不进行增容;
如果大于则进行以下操作:
(1)开空间(2)将原有空间内容拷贝到新空间(3)销毁原有空间(4)改变指针指向
//reservevoid reserve(size_t new_capacity){if (new_capacity > capacity()){size_t sz = size();//开空间T* tmp = new T[new_capacity];//深拷贝size_t i = 0;while (i < sz){tmp[i] = _start[i];i++;}//释放原有空间delete[] _start;//改变指向_start = tmp;_finish = _start + sz;_end_of_storage = _start + new_capacity;}}
4、改变有效字符个数resize
改变有效字符个数分为以下几种情况:
(1)当newSize > size时,将新加的空间赋上传入的值;
(2)当newSize > capacity时,reserve增容,再赋值;
(3)当newSize < size时,直接改变_finish指针;
//resizevoid resize(size_t new_size, const T& val = T()){if (new_size > size()){if (new_size > capacity()){reserve(new_size);}iterator it = end();while (it != _start + new_size){*it = val;it++;}}_finish = _start + new_size;}
1、非const修饰的[]运算符重载函数
在获取index位置的值之前,需要判断边界,看是否越界访问;
非const修饰的可以访问,也可以修改内容;
T& operator[](size_t index){//判断边界assert(index < size());return _start[index];}
2、const修饰的[]运算符重载
const修饰的可以访问但是不能修改内容
const T& operator[](size_t index) const{//判断边界assert(index < size());return _start[index];}
1、交换函数Swap
void Swap(my_vector<T>& v){swap(_start, v._start);swap(_finish, v._finish);swap(_end_of_storage, v._end_of_storage);}
2、任意位置前插入一个值insert
插入前首先要判断边界条件和是否需要扩容;
//任意位置前插入iterator insert(iterator pos, const T& val){//判断边界assert(pos >= begin() && pos <= end());//获取pos的偏移量size_t len = pos - _start;if (_finish == _end_of_storage){size_t new_capacity = (_start == nullptr ? 1 : capacity() * 2);reserve(new_capacity);}iterator it = end();//更新pos的位置,防止增容之后pos失效pos = _start + len;while (it != pos){*it = *(it - 1);it--;}*pos = val;_finish++;return pos;}
因为传入的位置是迭代器,所以当增容时,会使迭代器失效,那么就必须要更新pos的位置,防止增容之后pos迭代器失效导致出现错误;
返回值也是一个迭代器,返回的是pos位置的迭代器,指向的就是新加入的元素的位置,这也是防止在插入元素时迭代器失效的问题;
3、删除任意位置元素erase
//删除任意位置iterator erase(iterator pos){//判断边界assert(pos >= begin() && pos < end());iterator it = pos + 1;while (it != end()){*(it - 1) = *it;it++;}_finish--;return pos;}
同插入,删除的返回的也是pos位置的迭代器,指向的就是删除之前下一个元素的位置,这也是防止在插入元素时迭代器失效的问题;
4、尾插,尾删
尾插(push_back)、尾删(pop_back)都是insert和erase两个函数的复用;
//尾插void push_back(const T& val){insert(_finish, val);}//尾删void pop_back(){erase(_finish - 1);}
本文发布于:2024-02-02 09:20:51,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170683685242839.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |