无论是string还是vector或者list他们的迭代器都有类似于指针的行为,解引用时都能访问其中的数值。
2.list重载->运算符时比较奇怪,
就像这样子,迭代器返回一个日期类型的指针,所以it-->的返回值是data的指针,常理来说应该是it->->-day才对,所以这里应该是省略了一个->运算符。
3.this指针指当前对象的整体指针,若是要对this指针做运算符运算,类里面应该有预期的运算符重载而达成目标。
4.list的析构函数不同于顺序结构的析构,因为他的空间是一个个分散的空间,所以得找到一个析构一个,可以用循环遍历和erase函数结合使用来清空list中的数据,再用delete释放list的头节点。就像下面这样
记得析构一块连续空间是要加[],其他不加哦,不然就坑了,写出了一个大bug。代码习惯一定要好,不然改都没法改。
然后就是比较麻烦的点了
1.迭代器是一个很好用的东西,在学习string时发现迭代器定义就是头尾指针,很简单,到使用vector的迭代器时发现它的成员变量就是重定义的迭代器,分别指向空间的头,最后一个有效数据的地址,和实际空间的最后一个地址,而list的迭代器是一个类它需要有前后指针来完成迭代操作,但是迭代器总共有四种,const和普通的,与逆置的,所以为了变量类型不同再写一个类未免太麻烦了。于是可以用类模板来实现不同的迭代器,当参数传入const类型时自动调用const迭代器,根据模板来完成迭代。但是如果单纯的给普通迭代器加上const修饰可能并不能解决问题,因为list的节点可能是多种不同类型的嵌套,而只给节点指针用const修饰而节点的引用和解引用没有被const限制,可能会导致节点的引用和解引用值被修改,所以在模板上就需要加上限制后两个参数实现,如图,
如果类中传入一个const修饰的实例化对象。那么对象就会根据参数进入const—iterator,又因为const_iterator的后两个参数只读所以他的&和*都不能被改变从而达成了只读迭代器的效果。
所以灵活运用模板可以很好的简化代码量,
但是再进行上述过程中遇到了一个问题,再写第二个模板是不小心将T本身也写成了const导致程序编译失败,找了很久不知道问题出在哪里,就像这样
可以看到第65行的第一个模板参数被加了const修饰,下面报错,因为是初学者也不知道是怎么回事,于是猜想可能是传参的时候实例化对象已经被const修饰,不能在发生一些其他的类型转换所以编译不过。
最后总结几个小问题:
1.STL类中end函数返回最后一个数的下一个位置,若是循环列表则end返回头指针。begin函数返回头指针的下一个位置,
2.在学习了string,vector和list总结他们的构造函数,拷贝构造以及重载=运算符有何不同:
string比较简单,他的构造就是开辟一段连续空间,拷贝的话就是先开辟空间再用memcpy函数就可以拷贝,并不涉及浅拷贝的问题。因为他储存的类型就是串。
vector的构造:虽然他也是一片连续的空间但是他储存的类型可以不只是内置类型,所以他开辟空间的类型取决于他存储的类型,因为vector在使用的时候需要标明用来储存什么样的信息。所以构造函数先将各个指针置为空,再插入的时候开辟空间,而他的拷贝构造就和string不一样了这里不在可以用memcpy拷贝因为可能会出现浅拷贝现象,导致delete出错,比如它里面存类的实例化对象,memcpy只会原封不动的拷贝指针变量,导致delete两次崩溃,重载=运算符也是同理。
list的构造:list的构造因为已经有了定义好的节点,所以无参构造就是初始化一个头节点,给头节点开一个空间,并且前后指针指向自己,而他的拷贝构造就是利用迭代器不断插入被拷贝对象的数据,这里有一个问题list声明了三个类分别是本身,节点,和迭代器,那么其他两个要不要手动写析构函数呢?
最后是这样子想的,_list_node有三个变量前两个指针变量的指向在list的析构中就被置为空了,因为在不断删除下就剩一个头节点,并且是循环指向自己,所以被干掉了,而T类型若是内置类型系统自己会干掉,若是类对象,则析构的任务就有对应类对象来完成,,所以这个不需要手动去写析构函数。那迭代器呢,迭代器就更不用了因为迭代器本身所用的空间就是list的空间,他会随着list释放跟着释放,但是——node最后会成为野指针吧,所以保险期间加上析构函数吧
然后关于上述三个类的构造函数就是这样了,还有一个点,当重载等于运算符是可以不传引用,利用他的拷贝构造的临时变量特性,交换数据就可以节省代码量,
然后就是类型不同物理意义相同的变量不能混为一谈,比如上述的node*和迭代器他们虽然都是节点的指针但是解引用却不同,node解引用得到一个节点,而迭代器解引用得到重载后的变量。
链表使用insert可能不会失效因为他是将节点插入在迭代器的前面。当前迭代器指向没有变,而顺序结构插入可能引起增容导致当前迭代位置换地址或者被释放,引起错误
标签:10,const,迭代,list,学习,拷贝,节点,指针 From: https://www.cnblogs.com/qjwxlj/p/17304164.html