1

好的,我想一劳永逸地清除一些东西。如果我有一个法线向量,例如:

std::vector<Object*> coll;

我想了解它的元素,我知道三种方法:

1.使用int索引,如:for(int i = 0; i < coll.size(); ++i)

2.使用type_t索引,同1.:for(size_t i = 0; i < coll.size(); ++i)

并通过以下方式访问 1 和 2 中的元素:coll[i]

或者

3.使用const_iterator,如:

std::vector<Object*>::const_iterator i;
for(i = coll.begin(); i != coll.end(); ++i)
       // stuff

并使用 . 访问元素*it

我注意到(并且听说)第三种方式是最防失败的方式,但是在解除分配向量时非常不愉快,因为当我使用 时const_iterator,如果我执行类似的操作delete (*it),甚至coll.erase(it)在解除分配之前,我的迭代器失去它的价值,然后我不能继续for循环。

这样做的建议/好方法是什么?

4

4 回答 4

3

您的前两种方法都不完全正确。正确的索引类型是

std::vector<Object*>::size_type

这就是size()返回的内容,也是operator[]的内容。

使用迭代器的方法是惯用的方法。你写了

当我使用 const_iterator 时,如果我在释放之前执行 delete (*it) 甚至 coll.erase(it) 之类的操作,我的迭代器就会失去它的值,然后我就无法继续执行 for 循环

这是不正确的。在类似的东西

// ..
std::vector<int *>::const_iterator it, end = v.end();
for ( it = v.begin(); it != end; ++it ) {
    delete *it;
}

您不会使迭代器无效it。您只需调用delete迭代器指向的内容。因此,您可以在delete.

于 2012-09-07T07:02:01.193 回答
1

#3一种更通用,它使您的代码更灵活。
如果在某个时间点您需要将标准库容器从std::vector其他容器更改为其他容器#3,那么其他容器将按原样工作。(注意使用!=代替<or>

于 2012-09-07T07:02:25.473 回答
1

size_t 通常是用于索引数组的正确类型,因为它基本上被定义为足够大以容纳对象的最大大小的类型。它实际上被定义为内存范围的大小,但也是保存数组索引的最佳类型,这样您就知道它会足够大。

在 64 位系统上,您可能能够拥有填充数百 GB 内存的数组,但 int 最多只能容纳 20 亿左右的数字,而 size_t 应该是索引系统可以处理的任何数组的合适类型。

于 2012-09-07T07:08:05.997 回答
1

你写了:

...甚至 coll.erase(it) 在解除分配之前,我的迭代器失去了它的价值,然后我不能继续 for 循环......

vector::erase返回指向集合中下一个有效元素的迭代器。因此你可以写:

std::vector<Object*>::const_iterator i;
for(i = coll.begin(); i != coll.end(); )
{
  i = coll.erase(i);
}

请注意,在这种情况下您不得增加i( i++)。

于 2012-09-07T07:10:22.607 回答