提要
QList删除元素的时候需要特别注意一点,将元素删除后链表中元素的排列。删除一个元素后,后面的元素会补到被删元素的位置,这样在for循环中若删除元素后继续执行下标++,则会少遍历元素。下面看一个示例。
示例
下面是出错的代码,删除元素后执行了下标++。
//参数大概说明,仅说明,不涉及定义
QListReso m_listResolution;//保存每块屏的分辨率
stuBigScreen m_stuBigScrInfo;//保存大屏列表的信息
//每块屏的分辨率
typedef struct resolutions{int row;//行数int col;//列数int width;//分辨率的宽int height;//分辨率的高
}ST_RESOLU;typedef QList<ST_RESOLU> QListReso;
typedef ST_RESOLU stuReso;//大屏列表信息
typedef struct bigScreInfo{int bigScreRow;//大屏的行数int bigScreCol;//大屏的列数QString strName;//大屏名称QListReso resoluList;//大屏列表中每块屏的分辨率
}ST_BIGSCR_INFO;typedef ST_BIGSCR_INFO stuBigScreen;
//以上仅为变量类型说明,提供以便理解下面代码void largeScreenListWidget::deleteDontExist()
{for(int i = 0; i < m_listResolution.size(); ++i){if(m_listResolution[i].row >= m_stuBigScrInfo.bigScreRow ||m_listResolution[i].col >= m_stuBigScrInfo.bigScreCol){m_listResolution.removeAt(i);}}
}
使用下标删除部分元素后,发现链表中还有部分满足删除条件的元素没有被删除,原因是在被删除元素后面的元素,会补上前面被删除元素的位置。此时再执行下标++,会跳过一个元素,故而当删除元素后,不能执行下标++,而要再在原来的被删除的元素的位置上再去判断一下是否满足删除条件。
正确的代码如下:
void largeScreenListWidget::deleteDontExist()
{for(int i = 0; i < m_listResolution.size(); ++i){if(m_listResolution[i].row >= m_stuBigScrInfo.bigScreRow ||m_listResolution[i].col >= m_stuBigScrInfo.bigScreCol){m_listResolution.removeAt(i);i--;}}
}
相比前面的代码,此段代码的实现中多了下标–,为了将删除元素后紧跟着补到被删除元素的位置上的元素也进行判断,这样所有的元素都会判断看是否满足删除条件。