14

リストがありますstd::list<T *> *l;。このリストは null ではなく、いくつかの値があります。私の問題は、アイテムに適切にアクセスする方法ですか? リストを反復処理する必要はありません。最初のアイテムだけが欲しい。

std::list<T*>::iterator it = l->begin();

if (it != l->end())
{
    // accessing T
    int value = (*it)->value(); // Is this safe?
}

またはnullもチェックする必要がありますか?

if (it != l->end() && (*it))
{
    // accessing T
    int value = (*it)->value();
}
4

2 に答える 2

16

使用を余儀なくされ、次のように定義されstd::list<T*> myList;ているとしましょう。T

struct T
{
    T(const char* cstr) : str(cstr){ }
    std::string str;
};

次に、std::list::front最初の要素にアクセスするために使用します。

std::string firstStr = myList.front()->str;

myList.front()この場合、リスト内の最初の要素への参照を返すことに注意してください。これは、この場合はポインターへの参照です。したがって、最初の要素へのポインターのように扱うことができます。

そして、あなたの質問にNULL: ポインターのコンテナーを使用する場合、オブジェクトが破棄されたら、コンテナーからポインターを削除する必要があります。ポインターの使用を開始すると、通常、これらのポインターが指すオブジェクトに関連するメモリ管理を担当することになります (これが、可能な限り常によりも優先std::list<T>する主な理由です)。std::list<T*>

NULLポインターよりもさらに悪いのは、ぶら下がっているポインターです。オブジェクトを作成するときに、そのアドレスをコンテナーに保存しますが、オブジェクトが破棄された後、このアドレスをコンテナーから削除しないと、このポインターが無効になり、メモリにアクセスしようとします。このポインターが指すと、未定義の動作が発生します。したがって、ポインタstd::listが含まれていないNULLことを確認するだけでなく、まだ存在する有効なオブジェクトへのポインタのみが含まれていることも確認する必要があります。

したがって、これらの要素をクリーンアップするときまでに、リストからポインターを削除し、それらが指しているオブジェクトを一度に削除していることに気付くでしょう。

std::list<T*> myList;

myList.push_back(new T("one"));
myList.push_back(new T("two"));
myList.push_back(new T("three"));
myList.push_back(new T("four"));

while (!myList.empty())
{
    T* pT = myList.front();                     // retrieve the first element
    myList.erase(myList.begin());               // remove it from my list
    std::cout << pT->str.c_str() << std::endl;  // print its member
    delete pT;                                  // delete the object it points to
}

次の質問も読む価値があります:
Can you remove elements from a std::list while iterating through it?
std::list::iterator を消去するとイテレータが無効になり、オブジェクトが破棄されませんか?

于 2013-03-01T10:59:43.473 に答える
0

list要素のnullチェックの必要性は、最初にリストに何を入れることができるかに完全に依存します。

リストにnullポインターが含まれている可能性がある場合は、要素にアクセスする前に、間違いなくNULLをチェックする必要があります。
それが不可能な場合は、チェックする理由もありません。

于 2013-03-01T10:23:08.030 に答える