MyTinySTL 简单分析(六)--vector.h

发布时间:2024年01月22日

目前在学习STL,看到一个开源的项目MyTinySTL,非常不错。想着照着这个代码自己敲一遍应该也能有些进步。然后就开始了学习过程。

首先分析的是vector

以下是由vector.h关联的所有头文件

终于可以分析vector.h

class vector 先定义了一些类型,

首先定义了下面两个,

typedef mystl::allocator<T> ????????????????allocator_type;
typedef mystl::allocator<T> ????????????????data_allocator;

后续的value_type, pointer等等都是从allocator来的,

typedef typename allocator_type::value_type ?????value_type;
typedef typename allocator_type::pointer ????????pointer;

......

然后定义了三个成员变量

iterator begin_; ???// 表示目前使用空间的头部
iterator end_; ?????// 表示目前使用空间的尾部
iterator cap_; ?????// 表示目前储存空间的尾部

1)定义了构造、复制、移动、析构函数

调用的内部函数

vector() noexcept

默认构造

try_init()

explicit vector(size_type n)

显示构造(使用默认值)

fill_init

vector(size_type n, const value_type& value)

构造(给定初值)

fill_init

vector(Iter first, Iter last)

构造函数

range_init

vector(const vector& rhs)

拷贝构造

range_init

vector(vector&& rhs) noexcept

移动构造

range_init

vector(std::initializer_list<value_type> ilist)

初始化列表构造

range_init

vector& operator=(const vector& rhs);

拷贝赋值操作符

vector& operator=(vector&& rhs) noexcept;

移动赋值

rhs的成员要设置为nullptr

vector& operator=(std::initializer_list<value_type> ilist)

初始化赋值

先构造tmp,然后使用swap交换

~vector()

析构函数

destroy_and_recover

然后成员变量设置为nullptr

2)定义了迭代器相关操作

begin()

return begin_;

end()

return end_;

rbegin()

return reverse_iterator(end());

rend()

return reverse_iterator(begin());

cbegin

return begin();

cend() const noexcept;

return end();

crbegin()

return rbegin();

crend()

return rend();

3)容器相关操作

empty()

return begin_ == end_;

size()

end_ - begin_

max_size()

capacity()

reserve()

预留空间大小

shrink_to_fit()

放弃多余的容量

4)访问元素相关操作

operatro[]

return *(begin_ + n);

at()

return (*this)[n];

front

return *begin_;

back()

return *(end_ - 1);

data()

return begin_;

5)修改容器相关操作

调用内部函数

assign()

fill_assign/ copy_assign

emplace()

在pos位置就地构造元素,避免额外的复制或移动开销;分为三种情况

  1. pos在末尾,而且有剩余的容量
  2. pos不在末尾,且有剩余容量
  3. 没有剩余容量了,这个时候需要分配空间,调用reallocate_emplace

emplace_back()

在尾部就地构造元素,避免额外的复制或移动开销

直接使用构造参数列表添加元素

push_back

在尾部插入元素

需要先构造出一个元素,然后再放到缓冲区;性能上不如emplace_back()

pop_back()

弹出尾部元素

insert()

类似于emplace,reallocate_insert替换了reallocate_emplace

erase()

删除pos位置的元素

clear()

resize()

重置大小,分两种情况

reverse()

swap()

与另一个vector交换

6)helper_functions

调用的函数

try_init()

分配16个空间

init_space(size_type size, size_type cap);

分配制定空间

fill_init(size_type n, const value_type& value);

uninitialized_fill_n

range_init(Iter first, Iter last);

destroy_and_recover(iterator first, iterator last, size_type n);

destroy

deallocate

get_new_cap(size_type add_size);

fill_assign(size_type n , const value_type& value);

copy_assign(IIter first, IIter last, input_iterator_tag);

copy_assign(FIter first, FIter last, forward_iterator_tag);

reallocate_emplace(iterator pos, Args&& ...args);

重新分配一块新的空间,并在pos处就地构造元素

reallocate_insert(iterator pos, const value_type& value);

和上一个区别就像emplace 和 insert区别一样,emplace不要求传入一个对象,而只需要创造对象所需的参数,而insert需要先把对象构造出来,再把对象拷贝过去

fill_insert(iterator pos, size_type n, const value_type& value);

填充n个相同的value

copy_insert(iterator pos, IIter first, IIter last);

把另外一个容器的[first,last)拷贝到现有的容器中

reinsert(size_type size);

重新分配一个vector,把原来的元素拷贝到新分配的地方,顺便shrink了一下,因为end_等于cap_

copy_assign根据第三个参数有两个版本,

copy(xx,xx,input_iterator_tag)

copy(xx,xx,forward_iterator_tag)

其中的实现方式也不同,

需要分析一下这两个tag的区别

input_iterator_tag 只能读,不能写

forward_iterator_tag 既能读又能写

7)重载了对于两个vector的比较操作符

函数名

说明

operator==

operator<

字典排序

operator!=

operator>

operator<=

operator>=

8)重载了对于两个vector的比较操作符

swqp(vector<T>& lhs, vector<T>& rhs)

文章来源:https://blog.csdn.net/gengxt2003/article/details/135744124
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。