Nếu bạn buộc phải sử dụng std::list<T*> myList;
và giả sử rằng T
được định nghĩa là:
struct T
{
T(const char* cstr) : str(cstr){ }
std::string str;
};
sau đó chỉ cần sử dụng std::list::front
để truy cập phần tử đầu tiên:
std::string firstStr = myList.front()->str;
Lưu ý rằng trong trường hợp này myList.front()
lợi nhuận tham chiếu đến phần tử đầu tiên trong danh sách của bạn, tham chiếu đến con trỏ trong trường hợp này. Vì vậy, bạn có thể xử lý nó giống như một con trỏ đến phần tử đầu tiên.
Và câu hỏi của bạn về NULL
: Khi bạn làm việc với vùng chứa con trỏ, con trỏ sẽ bị xóa khỏi vùng chứa khi đối tượng bị hủy. Khi bạn bắt đầu sử dụng con trỏ, điều này thường có nghĩa là bạn là người chịu trách nhiệm quản lý bộ nhớ được kết nối với các đối tượng mà các con trỏ trỏ tới (đó là lý do chính tại sao bạn nên thích std::list<T>
hơn std::list<T*>
luôn khi có thể).
Thậm chí tồi tệ hơn NULL
con trỏ là con trỏ tòn ten: Khi bạn tạo một đối tượng, lưu trữ địa chỉ của nó trong bao bì của bạn, nhưng bạn sẽ không loại bỏ địa chỉ này từ container của bạn một khi đối tượng là destructed, sau đó con trỏ này sẽ trở thành không hợp lệ và cố gắng truy cập vào bộ nhớ mà con trỏ trỏ tới sẽ tạo ra hành vi không xác định. Vì vậy, không chỉ bạn nên đảm bảo rằng std::list
của bạn không chứa các con trỏ NULL
, bạn cũng nên đảm bảo rằng nó chỉ chứa các con trỏ tới các đối tượng hợp lệ vẫn tồn tại.
Vì vậy, theo thời gian, bạn sẽ được dọn dẹp những yếu tố này, bạn sẽ thấy mình bỏ con trỏ ra khỏi danh sách của bạn và xóa đối tượng họ trỏ đến cùng một lúc:
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
}
Nó cũng đáng để đọc những câu hỏi sau:
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?
Bạn đang giữ con trỏ, vì vậy hãy kiểm tra 'NULL'. Hoặc sử dụng một 'std :: list'. –
juanchopanza
Điều gì khiến bạn quyết định sử dụng 'std :: list' thay vì 'std :: list '? –
LihO
Có thực sự cần thiết để sử dụng các con trỏ thô không? ... –