【本节目标】
-
vector的介绍及使用
-
vector深度剖析及模拟实现
1. vector的介绍及使用
1.1 初始vector

1.2 通过简单了解vector实现二叉树前序遍历

1.3 resize

1.4 reserve
错误示范:

其原因在于reserve的作用是提升容量但并没有提升有效存储个数,换句话来说即便我们开辟了100个空间但是顺序表的核心用法是依次往下存储以及依次进行读取,并不能如上这样直接进行访问以及赋值。
正确示范:

1.3 clear or shrink_to_fit

1.4 杨辉三角
1.4.1 模拟实现嵌套vector结构

1.4.2 画图演示:

1.4.3 代码实现:

顺序表中的核心功能和我们数据结构(c语言)中的实现基本一致,所以我们在调用上并不会深入去讲各种各样的函数,把核心函数了解即可,下面我们就要模拟实现vector。
2. 模拟实现vector
引言: 在本次模拟实现中,我们将采用模板类并且实现声明定义分离的方式 对vector深入解剖学习。
2.1 模拟实现vector类的声明

2.2 模拟实现构造函数

2.3 模拟实现析构函数

2.4 模拟实现size()

2.5 模拟实现capacity()

2.6 模拟实现reserve()

2.6.1 关于reserve()深拷贝的问题思考
重点:在对于平常内置类型 来说确实可以运行,但是如果类型换成自定义类型,则可能出现不必要的麻烦

解决方案:

2.7 模拟实现push_back()
冗余写法:

我们可以看到中间扩容部分和成员reserve()的实现方式基本一致,代码过于冗余,我们下面直接调用reserve()以保证代码简洁性。

搭配insert()进行使用:

2.8 模拟实现operator[]

2.9 模拟实现Print()

2.10 模拟实现begin()

2.11 模拟实现end()

2.12 通过以上成员函数实现基本数据插入与展示
2.12.1 方法一

2.12.2 方法二

2.13 模拟实现resize()

2.14 模拟实现insert()

拓展_1:

总结: 只是一次临时使用则没有太大问题,如果要当作经常使用则会出现问题,因为当我们顺序表需要进行异地扩容的时候,pos位置还停留在当前,并没有跟随扩容一起改变地址,所以我们在insert()里面先记录pos在顺序表中的位置,然后根据异地扩容重新为pos赋值新的对应位置。那么我们要做的pos实际上是实参的临时拷贝,pos的改变并不能对外面的实参做出任何的影响,所以在这个问题看来,我们并不能将it频繁使用。
解决办法:使用引用,修改自身

但是添加引用又会出现新的问题比如:

我们 v.begin() 作为临时变量进行传参,怎么能用引用进行接受呢?
聪明的朋友可以想到,我们在引用前面进行添加const处理从而权限下降 ,但是这样的写法又会造成了无法对pos进行修改,仿佛进入到了死循环中。
重点:
我们新的解决办法是: 返回新pos地址,it重新接收。

输出结果:

2.15 模拟实现erase()

输出结果:

但是这样的删除逻辑是不正确的,且看下面案例:
先看运行结果:

画图分析:

解决的办法其实很简单:

2.16 模拟实现拷贝构造函数

2.17 模拟实现swap()

2.18 模拟实现赋值运算重载

示例:

当执行 v1 = v 时,会首先调用拷贝构造函数,为赋值运算符重载函数的按值传递形参创建一个 v 的临时副本(因为形参是对象值而非引用),随后才会进入赋值运算符的函数体执行实际的赋值逻辑(如通过 swap 交换资源)。
2.19 模拟实现通用构造函数(模板类型_start,模板类型_finish)

输出结果:

2.19.1 拓展:类成员变量的初始化优先级规则
-
无构造函数时: 如果类没有显式定义构造函数,成员变量的缺省值(C++11 及以后支持的类内初始值)会被使用。
-
有构造函数但未显式初始化时: 如果构造函数存在但没有在初始化列表中显式初始化某个成员变量,则使用该成员变量的缺省值(如果有的话)。
-
构造函数初始化列表与缺省值同时存在时: 构造函数初始化列表中的值会覆盖成员变量的缺省值,无论二者是否相同。
2.20 模拟实现通用构造函数_添加n个x数据

某些场景下,以上代码会出现报错问题:

问题: 为什么我们报错会在一个看起来毫无关联的成员函数的地方??
XingC::vector<T>::vector(InputIterator first, InputIterator last)将int类型视为指针,对此进行解引用访问,造成非法寻址。XingC::vector<T>::vector(size_t n, const T val)由于参数10的类型默认是int类型 ,如果没有上面成员函数,优先进行隐式转换从而匹配;但是存在上面的函数重载,在匹配度上面,上面的函数匹配程度会更高。
解决办法: 让实参与形参的匹配程度更高,从而优先调用。

2.21 电话号码的字母组合

示例:

本章完~