C++进阶之路---STL---vector

vector

  • 一:vector简介
  • 二.vector的初始化方式
  • 三.vector的常见问题
      • 1.size()和capacity()的区别
      • 2.元素的构建方式
      • 3.访问容器内部元素的方式
        • 方式一:
        • 方式二:error : 有可能造成访问越界
        • 方式三:
        • 方式四:
        • 方式五:auto
            • auto注意点:需求决定实现
      • 4.const修饰迭代器自身
      • 5.data() 方式慎重使用
      • 6.reserve():预留空间
      • 7.resize():开辟空间,构造对象
      • 8.assign()
      • 9.回收空间
      • 10.元素插入:也可使迭代器失效
          • 方式一:insert()
          • 方式二:push_back()
          • 方式三:emplace()
          • 方式四:emplace_back()
  • 四.迭代器失效
      • 扩容过程中的迭代器失效
      • 插入过程中的迭代器失效
  • 五.vector和智能指针的联系
      • 裸指针
      • 智能指针

一:vector简介

C++进阶之路---STL---vector_第1张图片

二.vector的初始化方式

	vector<int>ar1;
	vector<int>ar2 = { 12,23,34,45,56 };
	vector<int>ar3(10, 23);//开辟10个空间每个空间的元素都是20
	vector<int>ar4({ 12,23,34,55,66 });//以列表的方式进行初始化

	vector<int>ar5(ar1);//拷贝构造
	vector<int>ar6(std::move(ar2));//移动构造

三.vector的常见问题

1.size()和capacity()的区别

C++进阶之路---STL---vector_第2张图片

2.元素的构建方式

C++进阶之路---STL---vector_第3张图片

C++进阶之路---STL---vector_第4张图片

3.访问容器内部元素的方式

方式一:

C++进阶之路---STL---vector_第5张图片

方式二:error : 有可能造成访问越界

C++进阶之路---STL---vector_第6张图片

方式三:

C++进阶之路---STL---vector_第7张图片

方式四:

C++进阶之路---STL---vector_第8张图片

方式五:auto

auto的底层是使用迭代器,故,自己设计的容器只要提供迭代器,此方法就可以实现
C++进阶之路---STL---vector_第9张图片

auto注意点:需求决定实现

1.对于内置类型,auto x: objvec 与 auto &x : objvec 没有区别
C++进阶之路---STL---vector_第10张图片
2.对于自己设计的类型最好使用 auto &x : objvec ,如此一来x就是元素的别名,访问时就是直接访问vector中的元素,不用重新构建副本,提升了访问效率
3.对于元素的访问不希望对其进行修改最好使用const auto &x : objvec

4.const修饰迭代器自身

C++进阶之路---STL---vector_第11张图片

5.data() 方式慎重使用

vector中的元素本身由对象进行管理,但是data()会暴露首元素的地址给op指针,此后op指针怎么修改怎么难受
C++进阶之路---STL---vector_第12张图片

6.reserve():预留空间

vector < int>vec;//此时容器默认大小是0,当向容器中插入数据时会进行扩容:0 1 2 4 8 16 32 64 . . . 容器的扩容代价是很高的,需要开辟更大的内存,将原来对象一个个拷贝构造到新内存,将原来内存上的对象析构,在将原来的内存释放。因此初始内存效率太低,扩容太频繁。如果提前知道容器中需要存放多少元素后就可以使用vec.reserve(20)提前预留20个元素的空间(此时容器是空的,元素个数为0,仅仅只是预留空间),此后再插入元素,在预留范围内就不会在扩容,大大提高了效率

C++进阶之路---STL---vector_第13张图片
C++进阶之路---STL---vector_第14张图片

7.resize():开辟空间,构造对象

vector < int>vec;
vec.resize(20);此时不仅给容器开辟内存空间,还会将内存上构造出默认值的对象(即就是容器不空,元素个数为20,元素都是0)

1.当new_cap的值大于当前capacity(),则进行扩容,并将空闲空间使用默认的构造函数进行构造;

2.当new_cap的值小于当前capacity(),则进行缩容,并将多余空间进行析构,capacity()不变,size()减小到new_cap

C++进阶之路---STL---vector_第15张图片
C++进阶之路---STL---vector_第16张图片

8.assign()

C++进阶之路---STL---vector_第17张图片

9.回收空间

vector在运行一段时间的时候,不断的放数据,不断的删除数.但是删除数据的过程中vector的容量并不改变,只是删除其中的元素对象.此时就存在问题:当前元素的个数远远小于vector的容量,所以就需要将vector的容量减下来,从而达到减小内存占用
C++进阶之路---STL---vector_第18张图片

10.元素插入:也可使迭代器失效

方式一:insert()

效率极其慢:
1.空间足够,需要进行数据的搬移
2.空间不够,先扩容,后进行数据的搬移

方式二:push_back()

C++进阶之路---STL---vector_第19张图片

方式三:emplace()

原位构造的实现 :使用定位new()
C++进阶之路---STL---vector_第20张图片

方式四:emplace_back()

C++进阶之路---STL---vector_第21张图片

四.迭代器失效

当迭代器指向空间被释放,迭代器必定失效

连续的插入和删除操作都会导致迭代器失效

  • earse(it);删除当前元素后当前元素的迭代器就会失效,其次数组中删除一个元素后,该元素后面的元素会向前移动一个位置,即就是获取到的新迭代器 it=earse(it) ;的位置还是当前位置,因此连续删除不仅需要重新获取迭代器位置,还需要注意逻辑操作
    C++进阶之路---STL---vector_第22张图片

  • insert(it,val);在it位置插入val,插入成功后迭代器虽然不会失效,但是逻辑上插入位置后面的元素都需要向后移动一位,it= insert(it,val) ;获取的依旧时当前位置的迭代器,因此如果要继续向后遍历就需要先++it
    C++进阶之路---STL---vector_第23张图片

当存在扩容时,原有数据空间会被析构,那么迭代器必定失效.
即就是当迭代器指向空间被释放,迭代器必定失效

扩容过程中的迭代器失效

C++进阶之路---STL---vector_第24张图片

插入过程中的迭代器失效

C++进阶之路---STL---vector_第25张图片

五.vector和智能指针的联系

裸指针

C++进阶之路---STL---vector_第26张图片

智能指针

当程序结束调用析构函数,需要将一个个的智能指针对象析构掉,因此会调用智能指针的析构函数,智能指针的析构函数有会将其指针指向的对象析构掉,因此做到了对vector里面对象进行自动管理

C++进阶之路---STL---vector_第27张图片

你可能感兴趣的:(C++进阶,c++)