zoukankan      html  css  js  c++  java
  • stl vector

    1     for(vector<Enemy*>::iterator it = enemy_vector_.begin();it != enemy_vector_.end();++it) {
    2 enemy_vector_.erase(it);
    3 //CCLog("%d num",enemy_vector_.size());
    4 it = enemy_vector_.begin();

    5 }
    vector进行erase后旧的容器会被重新整理成一个新的容器,it迭代器失效,变成一野指针。所以erase后,要赋给it一个新的迭代器。
      回过头来看上面写的代码明显有问题,erase 后又跳到第一个,但是++it,所以再erase时就漏掉了一个。修改后:
     1 bool EnemyManager::RemoveEnemies() {
    2 vector<Enemy*>::iterator it = enemy_vector_.begin();
    3 while(it != enemy_vector_.end()) {
    4 if((*it)->IsOutofMap()) {
    5 delete *it;
    6 enemy_vector_.erase(it);
    7 it = enemy_vector_.begin();
    8 } else {
    9 ++it;
    10 }
    11 }
    12 return true;
    13 }
      用vector时,出现了些问题,系统学习下:
    vector<T> v1; vector保存类型为T对象;默认构造函数v1为空。
    vector<T> v2; v2是v1的一个副本。
    vector<T> v3(n,i); v3包含n个值为i的元素。
    vector<T> v4(n); v4含有值初始化的元素的n个副本。
      关键概念:vector对象动态增长
    vector对象的重要属性就在于可以在运行时高效地添加元素。因为vector增长的效率高,在元素值已知的情况下,最好是动态地添加元素。这种增长方式不同于c语言中的内置数据类型,也不同于大多数其他编程语言的数据类型。虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。
      vector操作
    v.empty()如果v为空,则返回true,否则返回false。
    v.size()返回v中元素的个数。
    v.push_back(t)在v的末尾增加一个值为t的元素。
    v[n]返回v中位置为n的元素。
    v1=v2把v1的元素替换为v2中元素的副本。
    v1==v2如果v1与v2相等,则返回true。
    !=,<,<=,> and >=保持这些操作惯有的的涵义。
      vector对象的size
      empty和size操作类似于string的相关操作。成员函数size返回相应vector类定义的size_type的值。使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型。
    例:vector<int>::size_type
      向vector添加元素
    push_back操作接受一个元素值,并将它作为一个新的元素添加到vector对象后面。
      vector的下表操作
    vector中的对象是没有命名的,可以按vector中对象的位置来访问它们。通常使用下标操作符来获取元素。vector的小标操作类似于string类型的下表操作。
    vector的下表操作符接受一个值,并返回vector中该对应位置的元素。vector元素的位置从0开始。下例使用for循环把vector中的每个元素值都重置为0:
    for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)
      ivec[ix] = 0;
    和string类型的下标操作符一样,vector下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和string对象的下标操作类型,这里用size_type类型作为vector下标的类型。上例中,即使ivec为空,for循环也会正确执行。ivec为空则调用size返回0,并且for中的测试比较ix和0。第一次循环时,由于ix本身就是0,则条件测试失败,for循环一次也不执行。
      下标操作不添加元素(必须是已存在的元素才能用下标操作符索引。通过下标操作进行赋值时,不会添加任何元素)
    初学c++的程序员可能会认为vector的小标操作可以添加元素,其实不然:
    vector<int> ivec; // empty vector
    for(vector<int>::size_type ix = 0; ix != 10; ++ix)
      ivec[ix] = ix;
      关键概念:安全的反省编程
    习惯于c或java编程的c++程序员可能会觉得难以理解,for循环的判断条件用 != 而不是用<来测试vector下标值是否越界。c程序员难以理解的还有,上例中没有在for循环之前就调用size成员函数并保存其返回的值,而是在for语句头中调用size成员函数。
    C++程序员习惯于优先选用!=而不是<来编写循环判断条件。
    调用size成员函数而不保存它返回的值,在这个例子中同样不是必需的,但这反映了一中良好的编程习惯。在c++中,有些数据结构如vector也可以动态增长。
    像size这样的小库函数几乎都定义为内联函数,所以每次循环过程中调用它的运行代价是比较小的。
      迭代器简介
    除了使用下标来访问vector对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器(iterator)。迭代其是一种检查容器内元素并遍历元素的数据类型。
    标准库为每一种标准容器定义了一种迭代器类型。迭代器类型提供了比下标操作更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有容器都适用,现代C++程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的vector类型也是这样。
      容器的iterator类型
    每种容器类型都定义了自己迭代器类型,如vector:
    vector<int>::iterator iter;
    这符语句定义了一个名为iter的变量,它的数据类型是vector<int>定义的iterator类型。每个标准库类型都定义了一个名为iterator的成员,这里的iterator与迭代器实际类型的含义相同。 
      术语:迭代器和迭代器类型
    程序员首次遇到有关迭代器的术语时可能会困惑不解,原因之一是由于同一个术语iterator往往表示两个不同的事物。一般意义上指的是迭代器的概念;而具体而言时指的是由容器定义的具体的iterator类型,如vector<int>。
      begin和end操作
    每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回迭代器指向第一个元素:
    vector<int>::iterator iter = ivec.begin();
    上述语句把iter初始化为由名为vector操作返回的值。假设vector不空,初始化后,iter即指该元素为ivec[0]。
    由end操作返回的迭代器指向vector的“末端元素的下一个”。“超出末端迭代器(off-the-end iterator)”表明它指向了一个不存在的元素。如果vector为空,begin返回的迭代器与end返回的迭代器相同。
    由end操作返回的迭代器并不指向vector中任何实际的元素,相反,它只是起一个哨兵的作用,表示我俄美女已经处理完vector中所有的元素。
      vector迭代器的自增和解引用运算
    迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。
    迭代器类型可使用解引用操作符(*)来访问迭代器所指向的元素:
    *iter = 0;
    迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。从逻辑上说,迭代器的自增操作和int类型对象的自增操作类似。对int对象来说,操作结果就是把int类型值“加1”,而对象则是把容器中的迭代器中的迭代器“向前移动一个位置” 因此,如果iter指向第一个元素,则++iter直线个第二个元素。
    由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
      迭代器的其他操作
      == != 来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不想等。
      const_iterator,该类型只能用于读取容器内元素,但不能改变其值。 

    write by fgd

  • 相关阅读:
    HTML3 / 4 / 4.1 / 5 版本升级过程中,变化是怎么样的
    HTML head内所有标签,及其作用
    HTML 和 XHTML和区别
    HTML DOCTYPE 都有哪些,它们之前的区别和用途分别是什么?
    eclipse中英文切换--四种方式
    Eclipse Class Decompiler---Java反编译插件
    jdk历史版本下载
    eclipse优化(部分)
    博客迁移到github
    JavaScript:同步、异步和事件循环
  • 原文地址:https://www.cnblogs.com/wendao/p/cpp_stl_vector_learning.html
Copyright © 2011-2022 走看看