5

我有一些代码正在使用 gcc 4.7(来自 3.1)更新到 C++11

我有一个定义为类的私有成员的多重集:

multiset <Object*, objectcomp> objects_;

代码中有一段看起来像这样(p_q 是一对多集迭代器,很抱歉那条讨厌的线,迫不及待地想用 auto 替换它,哈哈):

void Terrain::removeObject(Object* obj){
    pair<multiset<Object*, objectcomp>::iterator, multiset<Object*, objectcomp>::iterator> p_q;
    multiset<Object*, objectcomp>::iterator p,q;
    q = NULL;
    p_q = objects_.equal_range(obj);
    for(p = p_q.first; p != p_q.second; p++){
        if(*p == obj) {q=p; break;}
    }
    if(q!=NULL){
        ... do stuff based on q no longer being null
    }
}

这将不再编译。您不能再将迭代器设置为 null 吗?什么是替代方案?(nullptr 也不起作用)

4

2 回答 2

7

将迭代器设置为 NULL 是不合法的。您可能很幸运,因为您的特定实现碰巧使用指针作为该类型的迭代器,但这仍然是非法的。

正确答案是:

q = objects_.end();

或者,在某些情况下:

q = multiset<Object*, objectcomp>::iterator();
于 2012-11-29T02:02:17.937 回答
2

您永远不能将迭代器设置为 NULL。如果上面的代码曾经奏效,那纯属偶然。考虑到多重集的任何合理实现,很难看出它是如何编译的,更不用说运行了。

获得“无处”迭代器的最佳方法是使用容器的末尾。替换q = NULLq = objects_.end()

另外,永远不要将原始指针放在容器中;这是对内存泄漏的公开邀请。您几乎可以肯定想要multiset<Object,comp>multiset<shared_ptr<Object>,comp>

于 2012-11-29T02:04:47.680 回答