vector

1. vector介绍及使用

1.1 vector介绍

 vector - C++ Reference

  •  vector(向量)是一个多功能的,能够操作多种数据结构和算法的模板类函数库
  •  vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,增加和压缩数据,一个容器中的所有对象都必须是同一种类型的。简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据
  • vector是一个类模板(class template)。使用模板可以编写一个类定义或函数定义,而用于多个不同的数据类型

1.2 vector使用

1)vector常见构造

函数名称接口说明
vector()(重点)无参构造
vector(size_type n, const value_type& val = value_type())构造并初始化n个val
vector (const vector& x) (重点) 拷贝构造
vector (InputIterator first, InputIterator last)使用迭代器进行初始化构造
vector (initializer_list<value_type> il)使用initializer_list类型,这种类型的对象由编译器从初始化列表声明中自动构造,初始化列表声明是用大括号括起来的逗号分隔元素列表
    vector<int> v1;                                
    vector<int> v2(4, 100);                      
    vector<int> v3(v2.begin(), v2.end());  
    vector<int> v4(v3);

    vector<int> v5({1,2,3,4,5});
    vector<int> v6={1,2,3};

2)iterator 的使用

接口说明
begin+end获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下 一个位置的iterator/const_iterator
rbegin+rend获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置 的reverse_iterator

3) 空间容量

函数接口说明
size数据个数
capacity空间容量大小
empty判空
resize(重点)改变size大小,再初始化
reserve(重点)改变capacity大小
  • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是 根据具体的需求定义的
  • resize在开空间的同时还会进行初始化,影响size

4)增删查改

函数

接口说明

push_back(重点)尾插
pop_back (重点)尾删
find查找。(注意这个是算法模块实现,不是vector的成员接口)
insert在pos位之前插入val
erase

删除pos位的数据

swap交换两个vector的数据空间
operator[] (重点)像数组一样访问

1.3 vector 迭代器失效问题(重点)

     vector的迭代器就是原生态指针T* 。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)

  迭代器失效解决办法:在使用前,对迭代器重新赋值即可

1) 扩容引起的野指针问题

  会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、 assign、push_back等

 解决方法:给 i 重新赋值即可

2)删除指定位置数据

v.erase(pos);
 cout << *pos << endl; // 此处会导致非法访问

  erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end 的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了

但下方代码运行成功,因为避免了数据位置问题

//删除所有偶数
auto i = v1.begin();
while (i != v1.end())
{
	if (*(i) % 2 == 0)
		v1.erase(i);
	else
		i++;
}
for (auto e : v1)
{
	cout << e << " ";
}
cout << endl;

 3)注意

  Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端。

2.vector模拟实现

2.1 实现

vector的模拟实现

2.2 使用memcpy拷贝问题

  •   memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存 空间中
  •   如果拷贝的是自定义类型的元素,memcpy既高效又不会出错
  •   如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时就会出错,因为memcpy的拷贝实际是浅拷贝

  上方代码实现reserve扩容时没有用memcpy浅拷贝,而是使用赋值重载深拷贝,使指向新地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值