如果我有一个包含指向类的指针的STL列表并想要访问一个类成员,我该如何处理?具体来说,我需要能够删除列表中的成员,每个成员都有一个具有唯一ID的成员。
所以我有类似的东西:
class Actor{
private:
int id;
public:
int getActorID(){ return id;};
};
std::list<Actor *> actorList;
std::list<Actor *>::iterator i;
因此,如果每个actor都有一个唯一的id,我怎么能删除具有特定ID的actor呢?我一直在使用手动编码的链表,但我想把它切换到STL。唯一的问题是我无法弄清楚如何访问方法getActorID()来找到要删除的节点。谢谢你的帮助。
答案 0 :(得分: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
答案 1 :(得分:1)
迭代器的作用类似于指针,因此为了调用存储为STL容器中指针的对象的成员函数,需要取消引用两次:
std::list<Actor*>::iterator iter = actorList.begin();
(*iter)->getActorId();
或者:
(**iter).getActorId();
答案 2 :(得分:1)
对可能进行多次擦除调用的容器进行Iterator for循环是等待发生的灾难,因为擦除通常会使传递给它的迭代器(以及指向擦除元素的任何其他迭代器)无效,并且无效的迭代器不能安全递增。只进行一次擦除调用的循环可以使用“break”。离开for循环而不使用无效的迭代器。
正如我告诉我的同事一周多次因此问题导致的分段错误后,如果要循环容器并调用erase,请使用while循环并确保获得下一项的有效迭代器(或结束())在调用erase之前。最简单的方法是在调用站点后增加迭代器。对于std :: list :: erase(iterator),还可以使用其返回值作为新的迭代器值。
答案 3 :(得分:0)
您必须使用迭代器,因为列表是顺序数据结构。
一旦有了迭代器,就可以使用间接运算符*
list<Actor *>::iterator it = actorList.begin();
Actor * innerPtr = *it;
innerPtr->yourMethod();
一旦您知道某个演员是要删除的演员,就可以使用方法erase(position);
使用ITERATOR:
if( innerPtr->getActorId() == <your condition> )
{
actorList.erase(it);
}
但是,如果您需要使用actor ID进行搜索,我建议您切换到不同的数据结构,例如关联容器(例如地图)。
答案 4 :(得分: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;
});
}