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

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?
}

或者我也应该检查是否为空?
if (it != l->end() && (*it))
{
    // accessing T
    int value = (*it)->value();
}

4
为什么你决定使用std::list<T *>而不是std::list<T> - LihO
需要使用裸指针吗?... - Mihai Todor
4
@LihO,这更好,一个指向指针列表的指针! - juanchopanza
1
现代C++编程的第一条规则是 - 不要使用该死的指针。 - Bartek Banachewicz
1
@LihO 实际上这不是我的决定。我正在使用的API返回一个指向指针列表的指针。 - shan
显示剩余3条评论
2个回答

19
如果你被迫使用 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::list时能否删除元素?
删除std::list::iterator是否会使迭代器失效并销毁对象?


目前 .front() 不是一个可用的函数了吗?如果是,那么应该使用什么替代方法? - serup

0

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

如果可能列表包含空指针,则在访问元素之前绝对应该检查NULL。
如果不可能存在空指针,则也没有理由进行检查。


我不同意,你应该始终检查NULL,特别是在DEBUG/开发构建中。如果不应该为NULL,则引发异常。 - Alex Chamberlain
@AlexChamberlain:在这种情况下,为什么不同时检查指针是否仍然引用有效的、存活的对象呢? - Bart van Ingen Schenau
如果我能想到一种方法,我会在DEBUG版本中使用它。 - Alex Chamberlain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接