C++ 如何访问 std::list 的第一个元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15155291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access the first element of std::list?
提问by shan
I have a list std::list<T *> *l;
. this list is not null and has some values. My problem is how to access items properly? i do not need to iterate over the list. i just want the first item only.
我有一个清单std::list<T *> *l;
。这个列表不为空并且有一些值。我的问题是如何正确访问项目?我不需要遍历列表。我只想要第一项。
std::list<T*>::iterator it = l->begin();
if (it != l->end())
{
// accessing T
int value = (*it)->value(); // Is this safe?
}
or should i check for null also?
或者我也应该检查 null 吗?
if (it != l->end() && (*it))
{
// accessing T
int value = (*it)->value();
}
回答by LihO
If you are forced to use std::list<T*> myList;
and let's say that T
is defined as:
如果您被迫使用std::list<T*> myList;
并假设其T
定义为:
struct T
{
T(const char* cstr) : str(cstr){ }
std::string str;
};
then just use std::list::front
to access first element:
然后只用于std::list::front
访问第一个元素:
std::string firstStr = myList.front()->str;
Note that in this case myList.front()
returns a reference to first element in your list, which is reference to pointer in this case. So you can treat it just like a pointer to the first element.
请注意,在这种情况下,myList.front()
返回对列表中第一个元素的引用,在这种情况下是对指针的引用。所以你可以把它当作指向第一个元素的指针。
And to your question about the NULL
: When you work with the container of pointers, the pointer should be removed from the container once the object is destructed. Once you start using pointers, it usually means that you are the one who becomes responsible for the memory management connected with objects that these pointers point to (which is the main reason why you should prefer std::list<T>
over std::list<T*>
always when possible).
关于您的问题NULL
:当您使用指针容器时,一旦对象被破坏,指针就应该从容器中移除。一旦你开始使用指针,这通常意味着你是谁成为负责与对象,这些指针指向相连接的存储管理的一个(这是最主要的原因,你应该更喜欢std::list<T>
在std::list<T*>
总是在可能的情况)。
Even worse than NULL
pointers are dangling pointers: When you create an object, store its address in your container, but you will not remove this address from your container once the object is destructed, then this pointer will become invalid and trying to access the memory that this pointer points to will produce undefined behavior. So not only that you should make sure that your std::list
doesn't contain NULL
pointers, you should also make sure it contains only pointers to valid objects that still exist.
比NULL
指针更糟糕的是悬空指针:当你创建一个对象时,将它的地址存储在你的容器中,但是一旦对象被破坏,你就不会从容器中删除这个地址,那么这个指针将变得无效并试图访问内存这个指针指向会产生未定义的行为。因此,您不仅应该确保std::list
不包含NULL
指针,还应该确保它只包含指向仍然存在的有效对象的指针。
So by the time you will be cleaning up these elements, you will find yourself removing pointers from your list and deleting objects they point to at once:
因此,当您清理这些元素时,您会发现自己从列表中删除指针并立即删除它们指向的对象:
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
}
It's also worth to read these questions:
Can you remove elements from a std::list while iterating through it?
Doesn't erasing std::list::iterator invalidates the iterator and destroys the object?
阅读以下问题也值得一读:
您可以在迭代时从 std::list 中删除元素吗?
擦除 std::list::iterator 不会使迭代器无效并破坏对象吗?
回答by Bart van Ingen Schenau
The need for a null-check of the list element depends entirely on what can be put into the list in the first place.
是否需要对列表元素进行空检查完全取决于首先可以放入列表的内容。
If it is possible that the list contains null pointers, then you most definitely should check for for NULL before accessing the element.
If it is not possible, then there is also no reason to check.
如果列表可能包含空指针,那么您绝对应该在访问元素之前检查 NULL。
如果不可能,那么也没有理由检查。