其他分享
首页 > 其他分享> > 关于list iterator not incrementable的解决方法

关于list iterator not incrementable的解决方法

作者:互联网

关于list iterator not incrementable的解决方法

编译环境:VS2015
语言:C++
参考博客:https://blog.csdn.net/qingtianweichong/article/details/9531919

话休絮烦,直接贴上报错图片:
在这里插入图片描述
看到list字样,应该是list容器部分出现了问题。下面贴出使用list容器的代码块:

1.错误源码

双向链表list及迭代器声明部分:

list<Bullet*> m_bullets;
   m_bullets.clear();//使用clear可以清除掉链表的内容
   list<Bullet*> ::iterator bp;//迭代器

遍历list链表

for (bp = m_bullets.begin(); bp != m_bullets.end(); bp++)
	{
		if (!((*bp)->IsDisappear()))
		{
			(*bp)->Display();//提领操作之后,提取的是指针变量
			(*bp)->Move();
		}
		else
		{
			delete *bp;//删除这个指针指向的内存,迭代器还存在
			m_bullets.erase(bp);
		}	
	}

代码的主要目的是实现发射炮弹,当炮弹在显示区域时,进行显示和移动。当炮弹飞出屏幕外面时,进行炮弹的销毁:
一是通过删除指向炮弹内存的指针,用delete语句实现,二是清除掉指向该炮弹的迭代器,用erase()函数实现。

2.错误分析

乍一看,使用迭代器遍历链表 在逻辑上没什么问题啊。剩下的就是erase函数和list有关了。重新研究了erase()函数原理后,总结出以下重要三点:

  1. erase()函数用于在顺序型容器中删除迭代器p所指向的元素。
  2. 返回值是一个迭代器,且当前迭代器已经失效。
  3. 该迭代器指向被删除元素后面的元素。

对于第二点,是本错误的关键所在。即使erase函数有返回值,不用变量接受返回值也没关系。但是erase使用后必须用迭代器接受这个返回值,否则会产生出乎意料的结果。这样才能使遍历进行下去。

对于第三点,代码中for循环的最后还有 bp++ 迭代器自加的操作。也就是说删除一个节点后,迭代器已经指向了下一个要遍历的节点。执行bp++后,被删除节点的后一个节点会被跳过。那么被跳过的炮弹就不会在屏幕上Display和Move了。

3.修正

for (bp = m_bullets.begin(); bp != m_bullets.end(); )//去掉bp自加的操作
	{
		if (!((*bp)->IsDisappear()))
		{
			(*bp)->Display();
			(*bp)->Move();
		}
		else
		{
			delete *bp;
			bp = m_bullets.erase(bp);
			//用当前迭代器接受erase返回的迭代器
			
			continue;
			//此时的迭代器已经移到下一位,跳过循环,不再执行下面的bp++;
		}
		bp++;
	}

修改过后就不再报错了
欢迎在评论区补充留言~

标签:incrementable,iterator,迭代,++,list,erase,bp,bullets
来源: https://blog.csdn.net/Alan_Walker_One/article/details/115025441