2

如果我有一个包含指向类的指针的 STL 列表并想要访问类成员,我将如何处理?具体来说,我需要能够删除列表中的成员,每个成员都有一个具有唯一 ID 的成员。

所以我有类似的东西:

class Actor{

    private:
    int id;

    public:
    int getActorID(){ return id;};
};

std::list<Actor *> actorList;

std::list<Actor *>::iterator i;

因此,如果每个演员都有一个唯一的 id,我怎么能删除具有特定 ID 的演员?我一直在使用手动编码的链接列表,但我想将其切换到 STL。唯一的问题是我不知道如何访问方法 getActorID() 来查找要删除的节点。谢谢你的帮助。

4

5 回答 5

3
std::list<Actor *>::iterator it;

std::list<Actor *>::iterator iStart = actorList.begin() ;
std::list<Actor *>::iterator iEnd = actorList.end() ;
for (it=iStart ;it!=iEnd;++it)
{
if (*it->getActorId() == searchedId)
  {
   actorList.erase(it);
   break; //you have unique id's so you could delete a maximum 1 item
  }
}

也不要忘记你有其他选择

std::list::remove
std::list::remove_if

http://en.cppreference.com/w/cpp/container/list/remove

于 2012-10-13T22:09:51.227 回答
1

可能多次调用擦除的容器上的迭代器 for 循环是等待发生的灾难,因为擦除通常至少会使传递给它的迭代器(以及指向被擦除元素的任何其他迭代器)失效,并且失效的迭代器不能安全地递增。只调用一次擦除的循环可以使用“break;” 在不使用无效迭代器的情况下退出 for 循环。

迭代器失效规则

正如我在此问题导致的多个分段错误一周后告诉我的同事,如果您想循环容器并调用擦除,请使用 while 循环并确保您获得下一项(或结束)的有效迭代器()) 在您调用擦除之前。最简单的方法是在调用站点后递增迭代器。对于 std::list::erase(iterator),也可以使用它的返回值作为新的迭代器值。

列表迭代器不可递增

于 2012-10-15T16:16:31.263 回答
1

迭代器的作用类似于指针,因此为了调用存储为 STL 容器中指针的对象的成员函数,您需要取消引用两次:

std::list<Actor*>::iterator iter = actorList.begin();
(*iter)->getActorId();

或者:

(**iter).getActorId();
于 2012-10-13T22:07:52.240 回答
0

要找到您想要使用的节点,可以使用std::find_if()

#include <algorithm>
#include <list>
using namespace std;


class Actor{

    private:
    int id;

    public:
    int getActorID() const { return id;};
};


// a functor used for pre-C++11 since lambdas aren't supported
struct isActor
{
private:
     int target;

public:
    isActor( int target) : target(target) {}

    bool operator()( Actor const* pa) const
    {
        return pa->getActorID() == target;
    }
};


std::list<Actor *> actorList;

std::list<Actor *>::iterator i;

int main()
{
    // pre-C++11 technique
    i = std::find_if( actorList.begin(), actorList.end(), isActor(42));

    // C++11 lambda technique
    int id = 42;
    i = std::find_if( begin(actorList), end(actorList), [=](Actor const* pa) {
        return pa->getActorID() == id;
    });
}
于 2012-10-13T22:22:30.113 回答
0

您必须使用迭代器,因为列表是顺序数据结构。一旦有了迭代器,就可以向前移动并使用间接运算符提取指向对象的指针*

list<Actor *>::iterator it = actorList.begin();
Actor * innerPtr = *it;
innerPtr->yourMethod();

一旦你知道一个演员是要被删除的演员,你可以使用erase(position);USING THE ITERATOR 方法:

if( innerPtr->getActorId() == <your condition> )
{
    actorList.erase(it);
}

但是,如果您需要使用 actor ID 进行搜索,我建议您切换到不同的数据结构,例如关联容器(例如 map)。

于 2012-10-13T22:11:34.513 回答