zoukankan      html  css  js  c++  java
  • vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项

        vector<int> first;//Size()==2
        first.push_back(1);
        first.push_back(2);
        //first.insert(2);
    
        vector<int>second;//Size()==3 + assign??
        second.push_back(3);
        second.push_back(4);
        second.push_back(5);
        vector<int>::iterator it = first.begin();
        //second.assign(it,first.end());
        second.insert(second.end(),first.begin(),first.end());
    
    
        printf("first.size=%d
    ", first.size());
        printf("second.size=%d
    ", second.size());
        for (it = second.begin(); it != second.end(); it++)
            printf("second[]=%d
    ", *it);

    second 要插入first的内容,太长了。好麻烦。怎么就没有直接 push_back(vector) 的 重构函数呢??

    emplace 是C++11 里的 ,感觉跟这个 insert用法是一样的啊。

     assign 是完全替换的意思。 直接用 operator = 难道不就OK了么?

     reserve是修改vector目前数组 的大小。配套的是capacity()方法。获取数组的大小。

    resize是修改vector 内容的。配套的是size()方法。获取数据的个数。 size() <= capacity();

    --------------

    真想把 www.cplusplus.com 这个网站给抓下来,然后自己做一个站点。

    它没有评论;有些示例 非常不好。

    补充 vector 进行iterator 且 erase删除元素的注意事项

    ==============================

    【1】 首先,了解vector是数组,删除元素 会把后面的元素前移。

    for( iterator it =XX.begin();it!=XX.end();it++){...}

    【2】这里的it++ 只是 从前一个数组元素 移动到后一个数组元素,一般都是比较连续的地址,跟 vector<>里面的元素大小有关。

    【3】而且for循环中 it!=XX.end() 这个条件 是一个坑,因为 它 不是实时的,当元素删除后,XX.end() 的值(地址) 应该会变动,但是for循环中 不会。所以 for循环 中间的条件 最好 在 for循环内 代码区域 进行判断,则是实时的【我的描述能力实在有限,只能这么说了】。

    【4】可以使用 reverse_iterator 配合 erase 进行删除就安全一点

    下面给一个例子:

    #include <stdio.h>
    #include <vector>
    using namespace std;
    
    void iteratorVector(vector <int>&vInts){
        int i = 0;
        for (vector<int>::iterator it = vInts.begin(); it != vInts.end(); it++){
            printf("	[%d] => %d
    ", i++, *it);
        }
        printf("===== End Iterator Vector ====
    ");
    }
    
    void test_erase(vector<int>&vInts, int nId)
    {
        for (vector<int>::iterator it = vInts.begin(); it != vInts.end(); it++){
            if (*it == nId){
                it = vInts.erase(it);
                return;
            }
        }
    }
    
    void test_reverse_iterator_vector(vector<int> & vInts)
    {
        //这里的 rbegin 应该 和 iterator 的end() 类似;
        //这里的 rend   应该 和 iterator 的 begin() 类似;
    for (vector<int>::reverse_iterator it = vInts.rbegin(); it != vInts.rend(); it++){
            test_erase(vInts, *it);
            iteratorVector(vInts);
        }
        return;
        //====  等效代码  ====
        for (vector<int>::iterator it = vInts.end();;){
            if (it == vInts.begin())break;
            it--;
            test_erase(vInts, *it);
            iteratorVector(vInts);
        }
    }
    
    
    
    int main()
    {
        vector<int> playingUserID;
        playingUserID.push_back(1);
        playingUserID.push_back(2);
        playingUserID.push_back(3);
        playingUserID.push_back(4);
        playingUserID.push_back(5);
    
        iteratorVector(playingUserID);
        test_reverse_iterator_vector(playingUserID);
    
    }
    /*
    运行结果:符合预期
    --------------
    
    test_vector_rbegin_with_erase.obj
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    ===== End Iterator Vector ====
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    ===== End Iterator Vector ====
    [0] => 1
    [1] => 2
    [2] => 3
    ===== End Iterator Vector ====
    [0] => 1
    [1] => 2
    ===== End Iterator Vector ====
    [0] => 1
    ===== End Iterator Vector ====
    ===== End Iterator Vector ====
    
    */

    【5】如果要结合 iterator 与erase进行删除,那么要这么写代码:

    void test_iterator_vector(vector<int> & vInts)
    {
        for (vector<int>::iterator it = vInts.begin(); ; ){
            if (it == vInts.end())break;
            
            test_erase(vInts, *it);
            
    
            iteratorVector(vInts);
        }
    }
    /*
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
    ===== End Iterator Vector ====
            [0] => 2
            [1] => 3
            [2] => 4
            [3] => 5
    ===== End Iterator Vector ====
            [0] => 3
            [1] => 4
            [2] => 5
    ===== End Iterator Vector ====
            [0] => 4
            [1] => 5
    ===== End Iterator Vector ====
            [0] => 5
    ===== End Iterator Vector ====
    ===== End Iterator Vector ====
    */

    这里没有了 it ++  ,因为 erase删除后,后面的元素 前移,那么 it 刚才所指向的地址 ,现在 就是后一个元素了,刚好用到,就不需要 it ++ -- 了。

    顺便说下: it=vInts.erase(it); 这样 也是OK 的!!!!!

     【6】 最后要说的就是 STL 中的vector 以及其他容器 都是 非线程安全的,使用 iterator 迭代器 ,和 插入元素 不进行 加锁控制,会导致严重的问题。

    所以最好 自己 写一个 继承了 Mutex 功能的类的容器,使用stl 也就是这点风险了。

  • 相关阅读:
    (转).NET 多线程编程
    [WAP]WML学习笔记总结
    [计划]2010年1月的工作学习计划
    [计划]11月&12月学习与工作计划
    [HTTP]HTTP协议学习总结第一弹:RFC2616初读总结
    [培训总结]海量服务培训总结
    [随想]忙碌的2010
    Android电源管理
    Android 1.5: 飞行模式分析
    android JNI 调用
  • 原文地址:https://www.cnblogs.com/ayanmw/p/4649062.html
Copyright © 2011-2022 走看看