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?