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

イテレーターはポインターのように機能するため、STL コンテナーにポインターとして格納されているオブジェクトのメンバー関数を呼び出すには、2 回逆参照する必要があります。

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

または:

(**iter).getActorId();
于 2012-10-13T22:07:52.240 に答える
1

コンテナに対するイテレータの for ループは、消去の呼び出しを複数回行う可能性があり、最悪の事態が発生するのを待っています。なぜなら、消去は通常、少なくとも渡されたイテレータ (および消去された要素を指している他のイテレータ) を無効にし、無効化されたイテレータは安全にインクリメントできないためです。消去の呼び出しを 1 回だけ行うループでは、「break;」を使用できます。無効化された反復子を使用せずに for ループから抜け出す。

イテレータの無効化規則

この問題によって引き起こされた複数のセグメンテーション違反の 1 週間後に同僚に伝えたように、コンテナーをループして消去を呼び出したい場合は、while ループを使用して、次のアイテム (または終了) への有効なイテレーターを取得するようにしてください。 ()) 消去を呼び出す前に。これを行う最も簡単な方法は、呼び出しサイトで反復子を後置インクリメントすることです。std::list::erase(iterator) の場合、その戻り値を新しい反復子の値として使用することもできます。

リスト反復子はインクリメントできません

于 2012-10-15T16:16:31.263 に答える
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);
}

ただし、アクター ID を使用して検索する必要がある場合は、連想コンテナー (マップなど) など、別のデータ構造に切り替えることをお勧めします。

于 2012-10-13T22:11:34.513 に答える
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 に答える