252-C++ STL list

1.list的介绍和使用
在这里插入图片描述
2.vector中的reserve只对空间进行扩大,而不构造对象,resize将空间扩大,而且还会构造对象

所以reserve扩大的空间并不能使用像vec[0] = 10这样的赋值操作,因为厘米没有对象,只有空间,而resize是可以的,因为resize在扩容的时候还创建了对象,reserve的last指针指向的是第一个元素的前面,而resize中的last指针指向的最后元素的后面,

3.(面试常问)vector中的push_back(100)和push_back(Object(100))和emplace_back(100)之间的区别

push_back(100)是先用100去构建一个Object对象,构建出来的对象是一个无名对象,再将无名对象移动构造到指定的空间中,然后将无名对象析构

push_back(Object(100))是先构造一个无名对象,再将无名对象移动构造到指定的空间中,然后将无名对象析构

emplace_back(30)是在位置上直接构造对象

如果Object构造函数前面有explicit(明确)关键字,那么push_back(100)就不能编译通过了,因为不能将100隐式转化成Object(100);必须指明是Object类型,也就是push_back(Object(100))
在这里插入图片描述
4.对于C++来说,有空间不一定有对象,但是有对象一定会有空间

5.下面程序有什么不同?

对于objar来说,它是一个Object * 的数组,里面存放的是一个一个Object * 指针,当执行obja.push_back(new Object(20));时,里面的Obejct * 指针指向堆区的Object对象

而对于Object来说,它是一个Object类型的数组,里面存放的是一个一个的Object对象,当执行obj.push_back(Object(10))时,它是将Object对象直接构建在了obj数组中

当delete obj时,会把里面的对象析构掉,然后把空间回收,而对于objar来说,它只能把空间回收,而不能析构对象,因为对象不在指针数组objar中,无法释放指针所指向的空间

所以要使用智能指针,就能将指针所指向的对象全部析构掉
在这里插入图片描述
6.下面程序有何不同?

vector obj; obj.emplace.back(100);是能编译通过的,它是将100作为Object构造函数的参数,直接在指定空间中构建对象

而vector<Object*> objar; objar.emplace.back(100);是不能编译通过的,100不能转换成Object指针类型,它要的是一个地址,所以不能编译通过

7.唯一性智能指针将拷贝构造函数删掉了

8.list成员类型
在这里插入图片描述
9.list.begin()返回的是第一个节点的迭代器,list.end()返回的不是最后一个节点的迭代器,而是最后一个节点的next域的迭代器,也就是头节点的迭代器

std::list::iterator it = list.begin();
it++;
++it;

++it的效率要比it++要高的多,后置++首先要创建一个副本,然后将副本返回,而前置++返回的就是it本身,不需要去额外创建副本

对于内置类型来说,前置++和后置++是没有区别的,对于对象和迭代器来说,尽可能的使用前置++

list每push_back一次,都要从堆区申请空间

list中的迭代器是一种双向迭代器,可以++it指向下一个元素的迭代器,也可以–it指向前一个元素的迭代器

10.list的初始化方法
在这里插入图片描述
11.list的front和back返回的是引用,list没有重载[]和at(i)函数,因为list的地址空间并不连续

12.对于list来说,在头部插入和在尾部插入时间复杂度都为O(1),对于vector来说,尾部插入不需要移动数据,而头部插入需要移动数据

13.list函数
在这里插入图片描述
14.对于list来说,它的排序有一些特殊

15.下面程序,迭代器it是否失效?如果没有失效,打印出来的*it值是多少?

答案:没有失效,打印出来的*it的值为1
list和vector不同,vector在插入的时候,可能当前空间不足,要重新开辟构建,将数据拷贝过去,然后将原来的空间释放掉,就会导致原来的迭代器失效,而list在插入的时候不存在空间不足的问题,不会影响到其他的节点,所以迭代器不会失效,还是指向第一个元素,打印出来的值还是1,在1前面插入了一个10,也不会影响到迭代器的指向
在这里插入图片描述
16.当在删除节点的时候,如果将该节点删除了,就会导致该节点的迭代器失效

下面程序将会崩溃
在这里插入图片描述
17.下面程序ilist1.erase(it);会将迭代器指向的节点删除,那么迭代器就会失效
在这里插入图片描述
为了解决上述问题,可以在每次erase以后,将后续节点给给it

但是也有可能失效,一直删,删到最后一个元素7后,it将指向头节点
在这里插入图片描述
当我们把7删除时,返回的是指向头节点的迭代器,将头节点的迭代器删掉时就会出现错误
在这里插入图片描述
18.下面程序,能否达到unique的目的?

答案:不能
必须对ilist1进行排序ilist.sort();才能达到unique的目的
在这里插入图片描述
19.remove函数

不管list是有序的还是无序的,ilist1.remove(3)会将链表中所有的3都删掉

注意:不是删除一个,是将所有满足条件的都删除
在这里插入图片描述
在这里插入图片描述
20.list中的splice(拼接)函数
在这里插入图片描述
21.vector和list的区别
在这里插入图片描述
22.vector和list没有谁好谁坏,在不同环境下使用的容器不一样,只有在某种环境下最适合哪种容器,容器都有它存在的道理
在这里插入图片描述
23.什么时候改用vector?什么时候该用list?
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值