如何访问std::list的第一个元素

How to access the first element of std::list?

本文关键字:list 第一个 元素 std 何访问 访问      更新时间:2023-10-16

我有一个列表std::list<T *> *l;。这个列表不是空的,它有一些值。我的问题是如何正确访问项目?我不需要遍历列表。我只要第一项。

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();
}

如果你被迫使用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
}

这些问题也值得一读:
你能从std::列表中删除元素而遍历它吗?
删除std::list::iterator不会使迭代器失效并销毁对象吗?

是否需要对list元素进行空检查完全取决于首先可以放入列表中的内容。

如果列表可能包含空指针,那么在访问该元素之前一定要检查是否为null。