C++——vector超详细介绍

vector:

vector是表示可变大小数组的序列容器。即动态顺序表。

 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。 

相关接口:

构造函数:

  • vector() 无参构造
  • vector(size_type n, const value_type& val = value_type()) 构造并初始化n个val
  • vector (const vector& x); 拷贝构造
  • vector (InputIterator first, InputIterator last); 使用迭代器进行初始化构造

迭代器:

  • iterator的使用 接口说明
  • begin() 获取第一个数据位置的iterator
  • end() 获取最后一个数据的下一个位置的iterator
  • rbegin() 获取最后一个数据位置的reverse_iterator
  • rend() 获取第一个数据前一个位置的reverse_iterator
  • cbegin() 获取第一个数据位置的const_iterator
  • cend() 获取最后一个数据的下一个位置的const_iterator

容量空间:    每次扩容50%

  • size() 获取数据个数
  • capacity() 获取容量大小
  • empty() 判断是否为空
  • void resize (size_type n, value_type val = value_type()); 改变vector的size
  • void reserve (size_type n); 改变vector放入capacity      

vector增删查改:

  • void push_back (const value_type& val); 尾插
  • void pop_back(); 尾删
  • InputIterator find (InputIterator first, InputIterator last, const T& val);     查找。(注意这个是算法模块实现,不是 vector的成员接口)
  • iterator insert (iterator position, const value_type& val);  在position之前插入val
  • iterator erase (iterator position); 删除position位置的数据
  • void swap (vector& x); 交换两个vector的数据空间
  • reference operator[] (size_type n); 像数组一样访问

vector 迭代器失效问题:也是push_back()的缺陷

两层含义:

1. 无法通过迭代器++,--操作遍历整个stl容器。记作:第一层失效。

2. 无法通过迭代器存取迭代器所指向的内存。 记作:第二层失效。

vector迭代器的几种失效的情况:  push_back()的缺陷:

  • 当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。  
  • 当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。  
  • 当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。

insert/erase导致的迭代器失效:

// insert/erase导致的迭代器失效 
#include <iostream> 
#include <algorithm> 
#include <vector> using namespace std;
 
int main() {    
    int a[] = { 1, 2, 3, 4 };    
    vector<int> v(a, a + sizeof(a) / sizeof(int));
 
    // 使用find查找3所在位置的iterator    
    vector<int>::iterator pos = find(v.begin(), v.end(), 3);
 
    // 删除pos位置的数据,导致pos迭代器失效。    
    v.erase(pos);    
    cout << *pos << endl; // 此处会导致非法访问
 
    // 在pos位置插入数据,导致pos迭代器失效。    
    // insert会导致迭代器失效,是因为insert可    
    // 能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。    
    pos = find(v.begin(), v.end(), 3); 
    v.insert(pos, 30);    
    cout << *pos << endl; // 此处会导致非法访问
    return 0; 
}

vetor使用了连续分配的内存,安插操作时:

  1. 容器还有一定的容量(v.capacity())来容纳这个元素。如此一来,安插和移除操作不会因容器满而重新分配内存。在安插和移除操作后,作用点位置前的元素并没改变,而操作位置后的元素向后或向前移动一位。
  2. 插入元素后当发现开辟的空间不够了,就会开辟更大的空间来进行拷贝数据,这个时候原来的start、finish、endofstorage都会发生变化,所以要插入位置已经变化,而传过来的位置还是原来的位置,就会出现插入越界。

删除操作时:

erase迭代器失效是在删除一个元素的时候,后面的元素要向前挪动,所以迭代器指向的位置就会被前面的覆盖,这时候++迭代器,就会跳过删除元素的后一个。

解决迭代器失效方法:

删除解决:<此部分代码来源网络>


for (iter = cont.begin(); iter != cont.end();)
{
   (*it)->doSomething();
   if (shouldDelete(*iter))
      iter = cont.erase(iter);  //erase删除元素,返回下一个迭代器
   else
      ++iter;
}

erase方法可以返回下一个有效的iterator。这样删除后iter指向的元素后,返回的是下一个元素的迭代器,这个迭代器是vector内存调整过后新的有效的迭代器。

插入处理:<此部分代码来源网络>

我们在插入前计算出相对与start的相对距离,那么当插入时候我们用计算的距离还原pos进行插入。

Iterator Insert(Iterator position, const T& value)
    {

        assert(position < End() && position >= Begin());
        size_t off = position - start;
        if (finish == endofstorage)
        {
            Expand(Capacity() * 2);
        }

        position = off + start; // 注意跌掉器失效
        for (Iterator i = End(); i != position; --i)
        {
            *i = *(i - 1);
        }
        *position = value;
        ++finish;
        return position;
    }

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值