当前位置:网站首页>vector的模拟实现
vector的模拟实现
2022-06-22 14:34:00 【股神。】
vector的成员变量
- _start:指向元素开始的位置
- _finish:指向最后一个元素的下一个位置
- _endofstorage:指向从堆区开辟的空间的末尾的下一位置

template<class T>
class vector
{
public:
//迭代器
typedef T* iterator;
typedef const T* const_iterator;
//反向迭代器迭代器
typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
//、、、、、、
//各种成员函数
//、、、、、、
private:
iterator _start;
iterator _finish;
iterator _endofstorage;
};
构造函数
1、无参构造
vector()
:_start(nullptr)
,_finish(nullptr)
,_endofstorage(nullptr)
{
}
2、采用迭代器的构造方法
template<class InputerIterator>//新建一个模板参数是为了可以传多种迭代器,而不是只能传vector的迭代器
vector(InputerIterator first, InputerIterator last)//vector有一种构造方法是vector v(v1.begin(),v1.end())
:_start(nullptr)
,_finish(nullptr)
,_endofstorage(nullptr)
{
while (first != last)
{
push_back(*first);
++first;
}
}
3、拷贝构造
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
vector(const vector<T>& v)//拷贝构造必需传引用,如果不传引用,就是传值,传值又是一次拷贝构造,进而死循环,所以不能像operator=那样写。
:_start(nullptr)
,_finish(nullptr)
,_endofstorage(nullptr)
{
vector<T> tmp(v.begin(), v.end());
swap(tmp);
}
赋值运算符重载
vector<T>& operator=(vector<T> v)
{
swap(v);
return *this;
}
析构函数
~vector()
{
if (_start)
{
delete[] _start;//销毁所开辟的所有空间
_start = _finish = _endofstorage = nullptr;
}
}
reverse()扩容
size_t size() const
{
return _finish - _start;//指针-指针,因为同类型得到的是这段空间的元素的个数。
}
void reserve(size_t n)
{
if (n > capacity())
{
size_t sz = size();
T* tmp = new T[n];
if (_start)//_start不为空,说明原来有数据,要拷贝
{
//memcpy是浅拷贝,当T是string时,字符串是存在堆中的,string只存了指向这个字符串的指针、size、capacity。
//因此使用memcpy也只是把指针的地址重新赋值给了tmp,当delete[] _start;就已经销毁了字符串的空间。
//然后tmp又赋值给了_start,程序结束,调用析构函数,又要再次销毁字符串的空间,同一块空间被释放了2次,程序错误
//因此不能使用memcpy
//memcpy(tmp, _start, sizeof(T) * size());//大部分情况是对的,但是涉及深拷贝问题会有错误
for (size_t i = 0; i < sz; i++)
{
//相当于string =string 调用了string类中的operator=,operator是深拷贝。
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp;
// _finish = _start + size();这句代码有误,因为_start的位置改了,所计算的size也是错的,应该提前保存原来数组的大小,即sz
_finish = _start + sz;
_endofstorage = _start + n;
}
}
push_back
当_finish == _endofstorage说明空间不够需要扩容。
void push_back(const T& x)
{
if (_finish == _endofstorage)
{
reserve(capacity() == 0 ? 4 : (capacity() * 2));
}
*_finish = x;
++_finish;
}
resize()
void resize(size_t n, const T& val = T())//const &会延长匿名对象的生命周期,延长到整个作用域,而不是仅是这一行代码
{
if (n < size())//如果定义的空间比原来还要小,即让finish指向_start+n的位置,而不用销毁空间
{
_finish = _start+n;
}
else
{
if (n > capacity())//定义的n大于容量了,扩容
{
reserve(n);
}
while (_finish != _start + n)//赋值
{
*_finish = val;
_finish++;
}
}
}
insert
iterator insert(iterator pos, const T& x)//传迭代器是规定,看文档;返回值要返回新插入元素位置的迭代器,也是为了处理迭代器失效问题
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _endofstorage)
{
// 扩容会导致pos失效,扩容需要更新一下pos,因为扩容可能是异地扩容
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : (capacity() * 2));
pos = _start + len;
}
iterator end = _finish - 1;
//这个while循环是将数据往后挪一个位置
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = x;
_finish++;
return pos;
}
erase
iterator erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);//这里不能用=,因为可能要删除最后一个元素
iterator begin = pos + 1;//让pos后一个元素 覆盖 pos位置上的元素
while (begin < _finish)
{
*(begin - 1) = *begin;
begin++;
}
--_finish;
return pos;
}
剩余的简单成员函数
void pop_back()//尾删
{
assert(_finish > _start);
--_finish;
}
const T& operator[](size_t i)const
{
assert(i < size());
return _start[i];
}
T& operator[](size_t i)
{
assert(i < size());
return _start[i];
}
size_t capacity() const//返回容量大小
{
return _endofstorage- _start;
}
正向迭代器
const_iterator begin() const
{
return _start;
}
const_iterator end() const
{
return _finish;
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
反向迭代器
方向迭代器的rbegin在正向迭代的end上,反向迭代器rend在正向迭代器的begin上。
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
我们为反向迭代器新建了一个类
namespace Lgc
{
//反向迭代器的end就是正向迭代器的begin,反向迭代器的begin就是正向迭代的end,这样写是为了复用正向迭代器
//因为用的是模板,这个反向迭代器同时也可以给其他容器使用。(如vector)
template<class Iterator,class Ref,class Ptr>
class reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> self;
public:
reverse_iterator(Iterator it)
:_it(it)
{
}
Ref operator*()
{
Iterator prev = _it;//prev不能是self类型,因为如果是self则prev是个反向迭代器,--还是一个反向迭代器,在*就是调用自己的operator*,然后一直调用自己的operator*,直到栈溢出(3.15 2:41:45) 我们的本意是去调用正向迭代器的operator*
return *(--prev);//因为rbegin在正向迭代器的end上,而end的位置在_finish的位置上,要获取元素,所以要--
}
Ptr operator->()
{
return &(operator*());
}
self& operator++()
{
--_it;
return *this;
}
self operator++(int)
{
self tmp(*this);
--_it;
return tmp;
}
self& operator--()
{
++_it;//因为是反向迭代的原因,--在逻辑是就是++
return *this;
}
bool operator!= (const self& rit) const
{
return _it != rit._it;//这个不等于是调用了正向迭代器的运算符重载!=
}
private:
Iterator _it;
};
}
边栏推荐
- 推荐几个AI智能平台
- Show me my personal work list for the past two years. I earn 6K a month in my spare time. It's so delicious to have a sideline
- SDVO:LDSO+语义,直接法语义SLAM(RAL 2022)
- Yilian technology rushes to Shenzhen Stock Exchange: annual revenue of RMB 1.4 billion, 65% of which comes from Ningde times
- Meet webassembly again
- 晒晒我这两年的私活单,业余时间月入6k,有份副业也太香啦
- I took a private job and earned 15250. Is it still necessary to do my main business?
- 跨界融合创意创新,助力提高文旅夜游影响力
- Ml notes matrix fundamental, gradient descent
- What does Alibaba cloud's cipu release mean for enterprise customers?
猜你喜欢

快速玩转CI/CD图形化编排

ROS2前置基础教程 | 小鱼教你用CMake依赖查找流程

Verilog使用inout信号的方法

What happened to those who didn't go to college

Ultimate efficiency is the foundation for the cloud native database tdsql-c to settle down

New hybrid architecture iformer! Flexible migration of convolution and maximum pooling to transformer

Keil simulation and VSPD

Token processing during API encapsulation

Countdown to the conference - Amazon cloud technology innovation conference invites you to build a new AI engine!

Application of mongodb in Tencent retail premium code
随机推荐
【一起上水硕系列】Day Three - video
华为机器学习服务银行卡识别功能,一键实现银行卡识别与绑定
米哈游六月社招火热开启!500+岗位,超多HC,就在这个夏天(附内推方式)
HMS Core新闻行业解决方案:让技术加上人文的温度
历时100天、小鱼搭建了个机器人交流社区!!现公开邀请版主中!
类似attention nlp
What does password security mean? What are the password security standard clauses in the ISO 2.0 policy?
mysql如何修改存储引擎为innodb
新版负载均衡WebClient CRUD
壹连科技冲刺深交所:年营收14亿 65%收入来自宁德时代
模板特例化 template<>
Are there many unemployed people in 2022? Is it particularly difficult to find a job this year?
Token processing during API encapsulation
DDD understanding of Domain Driven Design
GBASE现身说 “库” 北京金融科技产业联盟创新应用专委会专题培训
Ask if you want to get the start of sqlserver_ Is there a good way for LSN?
(pytorch进阶之路二)word embedding 和 position embedding
Database connection pool: stress testing
Rosbag使用命令
How MySQL modifies a field to not null