• STL : List使用时应注意的问题


    这篇文章所述只是本人遇到的问题,仅供参考。

    #include<list>
    #include<iostream>
    
    using namespace std;
    
    class Foo
    {
    public:
        Foo(int i) {m_iData = i;}
        void setData(int i ) {m_iData = i;}
        int GetData() {return m_iData;}
    private:
        int m_iData;
    };
    // 为了提高可读性,定义容器和迭代器的名字
    typedef list<Foo*> FooList;
    typedef FooList::iterator FooListItor;
    
    void main()
    {
        FooList c; // 创建一个链表容器
    
    //将三个不同的元素填入链表中
        c.push_back(new Foo(1));
        c.push_back(new Foo(2));
        c.push_back(new Foo(3));
    //迭代遍历链表
        for(FooListItor itor = c.begin();itor != c.end();)
        {
            if((*itor)->GetData() == 2)
            {
                delete (*itor);
                itor = c.erase(itor);
            }
            else
                ++itor;
        }
    
    //确保所有的对象被删除,链表不会自动完成该项任务
    for(FooListItor itor2 = c.begin(); itor2 != end();++itor2)
        delete (*itor2);
    }    

    使用指针指向动态分配内存的结构或对象时,有几件事情需要注意。

    1. 你要负责在使用完对象后释放所有分配的内存。容器并不知道将使用何种类型,所以它们不可能帮你自动释放内存。

    2. 许多运算可能会失败,这是因为它们直接对对象或结构的指针进行操作,而不是对对象或结构本身。比如链表的sort()函数,它使用<运算符来比较值并以此结果进行排序。就算运算符对类Foo是合法的,但链表的排序仍是按照指针的实际值而不是对象中数据的值。因而有必要设计自己的比较运算符,在比较之前先对指针解引用。

    3.记住,复制容器时,复制的仅仅是指针而不是对象。如果产生了重复的指针,将极难确定哪一个对象需要删除。解决办法是使用智能指针(smart pointer),或避开容器间复制元素的STL的例程或算法。

    4.注意,在迭代遍历链表的时候,从链表中删除元素要非常小心。因为删除当前指向的元素将导致迭代器失效,所以你必须确保正确使用erase()函数的返回值,它是这个函数将检索出的容器中的下一个合法位置,通过将这个返回值分配给老的迭代器,我们就跳过了非法位置。但是这又给我们带来了新的问题。当for循环在循环结束处试图对迭代器递增,由于我们已经用erase()将迭代器递增到了下一个位置,因此就会出现问题。为了解决这个问题,我们将递增运算从for循环体移到了循环中的条件选择语句内,在元素没有删除时才进行递增。(一般来说,最好使用算法从容器中删除元素,而不是手工迭代来做,如算法remove_if()就能安全有效地进行该项操作)。

  • 相关阅读:
    撕裂寂寞
    创业中的“孙子兵法”
    生命的颜色占卜
    常常激励我们的36句话
    创建自己的3D虚拟身体!
    富人和穷人的八大差异
    有时,孤单是一种享受
    JavaScript类
    上网的十条基本礼节
    程序设计中的感悟
  • 原文地址:https://www.cnblogs.com/ll-10/p/5461481.html
Copyright © 2020-2023  润新知