企业网站建设公司丰台做网站被骗了怎么办

当前位置: 首页 > news >正文

企业网站建设公司丰台,做网站被骗了怎么办,视频制作专业软件,小红书推广方案目录 一.默认成员函数 二.扩容相关函数 三.[]重载 四.修改函数 五.迭代器 继上次写完string之后#xff0c;可以写一个vector练练手以及熟悉其底层。vector是一个顺序表#xff0c;相比普通数组不同点在于顺序表的数据必须是连续存放的。 一.默认成员函数 string是只存放字符…         目录 一.默认成员函数 二.扩容相关函数 三.[]重载 四.修改函数 五.迭代器 继上次写完string之后可以写一个vector练练手以及熟悉其底层。vector是一个顺序表相比普通数组不同点在于顺序表的数据必须是连续存放的。 一.默认成员函数 string是只存放字符而vector需要存放内置类型和自定义类型所以需要引入类模板。以下是vector的最外层框架。 templateclass T//类模板参数T是接收外面转进来的类型可以使内置也可以是自定义类型class vector{public://成员函数的定义private://内置成员变量是三个迭代器vector的迭代器实际上还是指针iterator _start nullptr; // 指向数据块的开始iterator _finish nullptr; // 指向有效数据的尾iterator _endOfStorage nullptr; // 指向存储容量的尾}; 以下是vector的默认成员函数重载和const 重载一般不需要手动写。 vector()//默认构造函数{}vector(int n, const T value T())//构造一个包含n个元素的vector每个元素都是value{resize(n, value);//直接用resize即可}templateclass InputIteratorvector(InputIterator first, InputIterator last)//通过一个迭代器区间构造vector{while (first ! last){push_back(*first);first;}}vector(const vectorT v)//拷贝构造函数{vector tmp(v.begin(), v.end());//复用迭代器区间构造函数完成拷贝然后再交换swap(tmp);}vectorT operator (vectorT v)//通过传值来完成拷贝然后再交换{swap(v);return this;}~vector()//析构函数{delete[] _start;//直接delete由于是delete[]所以即使是多层嵌套自定义类型或者vector或其他类型也会调用他们的析构函数这里需了解delete[]原理_start nullptr;_finish nullptr;_endOfStorage nullptr;} 二.扩容相关函数 扩容函数需要注意异地扩容时把原来空间的元素拷贝到新空间时需要使用赋值而不是memcpy或memmove。对于自定义类型并且实现了深拷贝的赋值就不会出现因为浅拷贝导致多次析构的问题。 size_t size() const{return _finish - _start;//返回当前元素个数}size_t capacity() const{return _endOfStorage - _start;//返回总容量大小}void reserve(size_t n)//扩容{if (n capacity())//判断目标扩容大小有没有大于总容量{T tmp new T[n];//直接创建新空间大小为nsize_t sz size();//记录扩容前的元素个数if (_start)//如果_start不为空如果为空也不用复制元素内容了{for (int i 0; i sz; i){tmp[i] _start[i];//这里如果用memmove或者memcopy对于自定义类型会发生多次析构的问题相当于浅拷贝所以还是用赋值如果自定义类型有实现深拷贝就没问题}delete[] _start;//这里把原来的删除如果是浅拷贝这里的删除了tmp里面的自定义类型指针就变成野指针了}_start tmp;//修改_start_finish tmp sz;//记录sz的好处_endOfStorage tmp n;}}void resize(size_t n, const T value T())//扩容或减容至n个元素扩容的话会用value填满所有空间{if (n size())//判断目标扩容大小是不是小于当前元素个数{T* tmp new T[n];//直接创建新空间大小为nfor (int i 0; i n; i){tmp[i] _start[i];//一个个拷贝这里用赋值和reserve原因完全一样}//下面也和reserve一样delete[] _start;_start tmp;_finish tmp n;_endOfStorage tmp n;}else if (n size())//这里是目标扩容大小大于当前元素个数{int i size();//记录当前元素个数reserve(n);//扩容while (i n){_start[i] value;//从当前元素的结尾开始填充直到容量达到目标扩容大小}_finish _start n;//更新_finish}} 三.[]重载 []重载需要断言是否越界以及还要实现const版本。 T operator//方括号重载{assert(pos size());return _start[pos];}const T operator const//const方括号重载{assert(pos size());return _start[pos];} 四.修改函数 修改函数需要注意insert的pos迭代器失效问题以及erase的迭代器失效对于外部的迭代器。 void push_back(const T x)//尾插{if (_finish _endOfStorage){reserve(capacity() 0 ? 4 : capacity() * 2);}_start[size()] x;//结尾插入元素_finish;//更新_finish//或者复用insert//insert(end(),x);}void pop_back()//尾删{erase(end());//直接调用erase函数尾删}void swap(vectorT v)//交换两个vector的成员变量{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endOfStorage, v._endOfStorage);}iterator insert(iterator pos, const T x)//在pos位置之前插入{assert(pos begin());//断言防止pos越界assert(pos end());size_t sz pos - _start;//计算并记录pos和_start的相对距离也是待会要插入的位置if (_finish _endOfStorage)//判断是否要扩容{reserve(capacity() 0 ? 4 : capacity() * 2);}//重点注意这里是insert迭代器可能失效的地方pos _start sz;//如果是异地扩容那么pos所指的位置会被删除就变成野指针了所以要更新pos位置之前记录的sz就有用了if (size())//如果当前元素个数不为0的话{//从后往前走然后把左边的数据挪到右边需要注意下标的越界问题iterator end _finish;while (end pos){*end (end - 1);//左边的数据挪到右边end–;}}_start[sz] x;//放入数据_finish;//更新_finishreturn pos;//返回插入元素的下一个位置也就是pos}iterator erase(iterator pos)//删除当前位置的元素{assert(pos begin());//判断pos是否越界assert(pos end());iterator prev pos 1;//记录pos位置的前一个位置//从左往右走然后把右边的数据挪到左边直接覆盖要删除的元素while (prev end()){(prev - 1) prev;//把右边的数据挪到左边prev;}_finish–;//更新_finish//这里是第二个迭代器失效问题如果外面的迭代器不接受erase返回的迭代器可能后面的删除会出问题return pos;//返回删除元素的下一个位置其实还是pos} 五.迭代器 vector迭代器就是原生指针以及实现const迭代器。 typedef T iterator;//vector的迭代器是原生指针和string一样typedef const T* const_iterator;//const迭代器iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;} 以上就是vector的模拟实现写完后不仅可以提升对代码的操作熟练度对于顺序表这种数据结构也能有更深的理解。