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

本文详细解析了开源项目MyTinySTL中vector类的定义、构造方法、迭代器操作、容器功能、元素访问、修改操作以及辅助函数,还涵盖了比较操作符的重载。

目前在学习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)

### 含义 `x0=x*vector.x-y*vector.y` 是一个赋值语句。在这个语句中,`x` 和 `y` 是两个变量,`vector` 可能是一个自定义的数据类型(如结构体、类等),`vector.x` 和 `vector.y` 是该数据类型的成员变量。语句的含义是将 `x` 乘以 `vector.x` 的结果减去 `y` 乘以 `vector.y` 的结果赋值给变量 `x0`。 ### 用途 该代码在不同的场景下可能有不同的用途: - **向量运算**:在计算机图形学、物理学模拟等领域,经常会涉及向量的运算。如果 `vector` 代表一个二维向量,那么这个语句可能是在进行向量的点积运算的一部分,或者是某种向量变换操作。 - **坐标变换**:在图像处理、游戏开发等领域,可能会对坐标进行变换。这个语句可能是将原坐标 `(x, y)` 经过某种线性变换后得到新的坐标 `x0`。 ### 适用编程语言 该代码的语法风格比较通用,以下几种编程语言都可能使用这样的代码: - **Python**:在 Python 中,`vector` 可以是一个自定义的类的实例,类中定义了 `x` 和 `y` 属性。示例代码如下: ```python class Vector: def __init__(self, x, y): self.x = x self.y = y x = 2 y = 3 vector = Vector(4, 5) x0 = x * vector.x - y * vector.y print(x0) ``` - **C++**:在 C++ 中,`vector` 可以是一个结构体或者类的对象。示例代码如下: ```cpp #include <iostream> struct Vector { double x; double y; }; int main() { double x = 2; double y = 3; Vector vector = {4, 5}; double x0 = x * vector.x - y * vector.y; std::cout << x0 << std::endl; return 0; } ``` - **Java**:在 Java 中,`vector` 可以是一个自定义类的对象。示例代码如下: ```java class Vector { double x; double y; public Vector(double x, double y) { this.x = x; this.y = y; } } public class Main { public static void main(String[] args) { double x = 2; double y = 3; Vector vector = new Vector(4, 5); double x0 = x * vector.x - y * vector.y; System.out.println(x0); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值