C++_vector_调用及模拟实现

【本节目标】

  • 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 拓展:类成员变量的初始化优先级规则

  1. 无构造函数时: 如果类没有显式定义构造函数,成员变量的缺省值(C++11 及以后支持的类内初始值)会被使用。

  2. 有构造函数但未显式初始化时: 如果构造函数存在但没有在初始化列表中显式初始化某个成员变量,则使用该成员变量的缺省值(如果有的话)。

  3. 构造函数初始化列表与缺省值同时存在时: 构造函数初始化列表中的值会覆盖成员变量的缺省值,无论二者是否相同。

2.20 模拟实现通用构造函数_添加n个x数据

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

问题: 为什么我们报错会在一个看起来毫无关联的成员函数的地方??

  1. XingC::vector<T>::vector(InputIterator first, InputIterator last) 将int类型视为指针,对此进行解引用访问,造成非法寻址。
  2. XingC::vector<T>::vector(size_t n, const T val)由于参数10的类型默认是int类型 ,如果没有上面成员函数,优先进行隐式转换从而匹配;但是存在上面的函数重载,在匹配度上面,上面的函数匹配程度会更高。

解决办法: 让实参与形参的匹配程度更高,从而优先调用。

2.21 电话号码的字母组合

示例:

本章完~

相关推荐
不吃土豆的马铃薯19 小时前
网络 IO 核心(同步/异步)概念笔记
服务器·c语言·开发语言·网络·c++·笔记
张小凡vip19 小时前
python的__init__.py说明
开发语言·前端·python
努力努力再努力wz19 小时前
【Redis入门系列】:从 hashtable到 listpack:深入理解 Hash 底层编码、字段级过期、核心命令与缓存应用
开发语言·数据结构·数据库·c++·redis·算法·缓存
小黑随笔19 小时前
Python asyncio 模块学习总结:从“等着”到“切出去干点别的”
开发语言·python·学习
qq_2949405519 小时前
Python环境搭建
开发语言·python
XMYX-019 小时前
40 - Go HTTP 客户端:从 http.Get 到高性能连接池
开发语言·http·golang
Daydream.V20 小时前
C++ 入门全攻略:从基础语法到核心特性
java·开发语言·c++
我是一颗柠檬20 小时前
【JDK8新特性】接口默认方法与静态方法Day8
java·开发语言·后端·intellij-idea
lulu121654407820 小时前
【开发者指南】Gemini 3.5开发入门:从API调用到Agent构建
java·开发语言·人工智能·python·ai编程
盲敲代码的阿豪20 小时前
Python 爬虫入门基础教程:从入门到实践
开发语言·爬虫·python