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\n", first.size()); printf("second.size=%d\n", second.size()); for (it = second.begin(); it != second.end(); it++) printf("second[]=%d\n", *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("\t[%d] => %d\n", i++, *it); } printf("===== End Iterator Vector ====\n"); } 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 也就是这点风险了。
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。