vector的实现和使用中的常见错误

实现构造函数时的调用模糊

image-20230106165740725

vector的构造函数有这四种,其中有两种在实例化的时候会有调用模糊的问题:

vector<int> v(10, 3); 

该代码的意义是:实例化一个vector对象,该对象有10个元素,每个元素是int类型的3。如果用我们自己实现的vector来执行上述代码时可能会发生错误。

image-20230106173741307

因为该代码的原意是调用fill(2)函数,但实际上调用的是range(3)函数,因为我们的参数10和3都是int类型,而fill(2)的两个参数类型分别是size_type和const value_type&,range(3)的两个参数类型都是InputIterator。编译器在选用构造函数的时候会更倾向于选择range(3),而该构造函数内部会对迭代器进行解引用,当传入两个int解引用时就会报错。

STL库中的做法是这样的:重载更适合的参数类型的构造函数。

image-20230106170901671

实现insert函数时的迭代器失效

image-20230106171746146

在使用insert函数时会传参数position,但是该函数内部是非常有可能进行扩容的。扩容会开辟新的内存、释放旧的内存,然后指向新的内存,但此时由于position仍旧指向旧的内存,就会发生迭代器失效问题。

image-20230106175052107

正确的做法是这样的:用变量先记录下position的偏移量,当扩容之后再利用偏移量更新position。

截屏2023-01-06 17.57.13

使用erase函数时的迭代器失效

image-20230106171807038

使用erase函数也会传参数position,它的返回值也是iterator。

当该函数删除position位置上的数据后,由于vector是个数组,所以该位置后面的元素会向前移动,就会导致position位置上仍有数据,linux下g++就是这样实现的。但Visual Studio并不是这样实现的,它的底层迭代器被封装成了类,一但该位置上的数据发生变化,该迭代器就会作废。这就是同一问题的两种编译器的不同做法,所以为了统一,普遍认为即使在g++下该情况也是迭代器失效。

正确的使用方法是:

image-20230106181322157

实现reserve函数使用memcpy函数导致的浅拷贝

image-20230106181611193

该函数是vector进行扩容的函数,扩容之后肯定会把原数组里的数据拷贝到新数组里,有些人这时会用memcpy函数,这时就会出错了。

对于内置类型,这里用memcpy函数没什么问题,但是对于自定义类型来说,用memcpy就会出错,因为memcpy只是按照字节拷贝数组里的数据,进行的是浅拷贝,例如:

image-20230106182747866

所以这里不能够用memcpy,这里就应该一步一步的用旧对象的数据来初始化新对象。

正确的做法如下:

image-20230106182911673

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云朵c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值