If you are forced to use std::list<T*> myList;
and let's say that T
is defined as:
struct T
{
T(const char* cstr) : str(cstr){ }
std::string str;
};
then just use std::list::front
to access first element:
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.
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).
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.
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?