list学习记录(c++)

list学习记录

数据结构

在这里插入图片描述
从上面的图示可以看出list实际上是一个双向的循环链表,list里面有一个__list_node类型的指针,__list_node又有三根指针。分别是begin,end,和data熟悉双向循环链表的应该很清楚各自的作用了,这里就不多讲了。就是后面有一个灰色的node,是双向循环链表的最后一个元素的下一个元素。
在这里插入图片描述
上面是迭代器的操作,迭代器实际是一个对象但是能够模拟指针的行为,*号操作符重载实际上是去取了node的数据域,->又去调用了星号操作符重载函数,返回数据域的指针还有前加加和后加加就是让迭代器去移动到链表的下一位。为了测试list是否是一个循环链表,下面写了一个测试:

#include <list>
#include <iostream>
using namespace std;

class Test
{
public:
    Test(string s)
    {
        str = s;
       cout<<"Test creat\n";
    }
    ~Test()
    {
        cout<<"Test delete:"<<str<<endl;
    }
    Test& operator=(const Test& test)
    {
        cout << "调用例赋值构造函数" << endl;
        this->str = test.str;
        return *this;
    }
    Test& CopyTest(const Test& test)
    {
        cout << "调用例拷贝构造函数" << endl;
        this->str = test.str;
        return *this;
    }
    string& getStr()
    {
        return str;
    }
    void setStr(string s)
    {
        str = s;
    }
    void print()
    {
        cout<<str<<endl;
    }
private:
    string str;
};

int main()
{
    list<Test> lst;
    Test test1("11");
    Test test2("22");
    Test test3("33");
    lst.push_back(test1);
    lst.push_back(test2);
    lst.push_back(test3);
    list<Test>::iterator it = lst.end();
    it++;
    test1.print();
    (*it).print();
}

在这里插入图片描述
从上面的结果是可以看出list是一个双向的循环链表的的,并且还将test1里面的内容重新拷贝了一份到list里面这样test1和list容器里面的内容就相互独立不会影响了。

#include <list>
#include <iostream>
using namespace std;

class Test
{
public:
    Test(string s)
    {
        str = s;
       cout<<"Test creat\n";
    }
    ~Test()
    {
        cout<<"Test delete:"<<str<<endl;
    }
    Test& operator=(const Test& test)
    {
        cout << "调用例赋值构造函数" << endl;
        this->str = test.str;
        return *this;
    }
    Test(const Test& test)
    {
        cout << "调用例拷贝构造函数" << endl;
        this->str = test.str;
    }
    string& getStr()
    {
        return str;
    }
    void setStr(string s)
    {
        str = s;
    }
    void print()
    {
        cout<<str<<endl;
    }
private:
    string str;
};
int main()
{
    list<Test> lst;
    Test test1("11");
    lst.push_back(test1);
    list<Test>::iterator it = lst.begin();
    it->print();
    cout << &(*it) << endl;
    cout << &test1 << endl;
    lst.erase(it);
    cout << &(*it) << endl;
    it->print();
}

在这里插入图片描述

这段代码就比较神奇了,我明明已经将test所指向的空间释放了,也确实调用了析构函数,但还是执行了print函数,我只能猜想这里虽然释放了空间但是没有将it指向nullptr,所以只要原来空间的内容还没擦除,应该还是可以访问的,但是这个迭代器已经失效了。为什么?

#include <list>
#include <iostream>
using namespace std;

class Test
{
public:
    Test(string s)
    {
        str = s;
       cout<<"Test creat\n";
    }
    ~Test()
    {
        cout<<"Test delete:"<<str<<endl;
    }
    Test& operator=(const Test& test)
    {
        cout << "调用例赋值构造函数" << endl;
        this->str = test.str;
        return *this;
    }
    Test(const Test& test)
    {
        cout << "调用例拷贝构造函数" << endl;
        this->str = test.str;
    }
    string& getStr()
    {
        return str;
    }
    void setStr(string s)
    {
        str = s;
    }
    void print()
    {
        cout<<str<<endl;
    }
private:
    string str;
};
int main()
{
    list<Test> lst;
    Test test1("11");
    Test test2("22");
    lst.push_back(test1);
    lst.push_back(test2);
    list<Test>::iterator it = lst.begin();
    it->print();
    cout << &(*it) << endl;
    cout << &test1 << endl;
    lst.erase(it);
    cout << &(*it) << endl;
    it->print();
    it++;
    it->print();
}

在这里插入图片描述
如果没失效就还能访问到下一个元素,但这里却报段错误,说明这个迭代器已经失效了,但是erase()会返回下一个好的迭代器:

#include <list>
#include <iostream>
using namespace std;

class Test
{
public:
    Test(string s)
    {
        str = s;
       cout<<"Test creat\n";
    }
    ~Test()
    {
        cout<<"Test delete:"<<str<<endl;
    }
    Test& operator=(const Test& test)
    {
        cout << "调用例赋值构造函数" << endl;
        this->str = test.str;
        return *this;
    }
    Test(const Test& test)
    {
        cout << "调用例拷贝构造函数" << endl;
        this->str = test.str;
    }
    string& getStr()
    {
        return str;
    }
    void setStr(string s)
    {
        str = s;
    }
    void print()
    {
        cout<<str<<endl;
    }
private:
    string str;
};
int main()
{
    list<Test> lst;
    Test test1("11");
    Test test2("22");
    Test test3("33");
    Test test4("44");
    lst.push_back(test1);
    lst.push_back(test2);
    lst.push_back(test3);
    lst.push_back(test4);
    list<Test>::iterator it = lst.begin();
    it++;
    it = lst.erase(it);
    it->print();
    it++;
    it->print();
    it--;
    it--;
    it->print();
}

在这里插入图片描述

如有错误希望指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值