实现构造函数时的调用模糊
vector的构造函数有这四种,其中有两种在实例化的时候会有调用模糊的问题:
vector<int> v(10, 3);
该代码的意义是:实例化一个vector对象,该对象有10个元素,每个元素是int类型的3。如果用我们自己实现的vector来执行上述代码时可能会发生错误。
因为该代码的原意是调用fill(2)函数,但实际上调用的是range(3)函数,因为我们的参数10和3都是int类型,而fill(2)的两个参数类型分别是size_type和const value_type&,range(3)的两个参数类型都是InputIterator。编译器在选用构造函数的时候会更倾向于选择range(3),而该构造函数内部会对迭代器进行解引用,当传入两个int解引用时就会报错。
STL库中的做法是这样的:重载更适合的参数类型的构造函数。
实现insert函数时的迭代器失效
在使用insert函数时会传参数position,但是该函数内部是非常有可能进行扩容的。扩容会开辟新的内存、释放旧的内存,然后指向新的内存,但此时由于position仍旧指向旧的内存,就会发生迭代器失效问题。
正确的做法是这样的:用变量先记录下position的偏移量,当扩容之后再利用偏移量更新position。
使用erase函数时的迭代器失效
使用erase函数也会传参数position,它的返回值也是iterator。
当该函数删除position位置上的数据后,由于vector是个数组,所以该位置后面的元素会向前移动,就会导致position位置上仍有数据,linux下g++就是这样实现的。但Visual Studio并不是这样实现的,它的底层迭代器被封装成了类,一但该位置上的数据发生变化,该迭代器就会作废。这就是同一问题的两种编译器的不同做法,所以为了统一,普遍认为即使在g++下该情况也是迭代器失效。
正确的使用方法是:
实现reserve函数使用memcpy函数导致的浅拷贝
该函数是vector进行扩容的函数,扩容之后肯定会把原数组里的数据拷贝到新数组里,有些人这时会用memcpy函数,这时就会出错了。
对于内置类型,这里用memcpy函数没什么问题,但是对于自定义类型来说,用memcpy就会出错,因为memcpy只是按照字节拷贝数组里的数据,进行的是浅拷贝,例如:
所以这里不能够用memcpy,这里就应该一步一步的用旧对象的数据来初始化新对象。
正确的做法如下: