如何将迭代器变量声明为类私有成员?双向链表迭代器初始化疑问
Hey there! Let's tackle your problem step by step. First, let's figure out how to declare the iterator using a reference to your linked list, then fix that annoying "reset every function call" issue.
1. Make Your Iterator Accept a List Reference
The reason DoublyLinkedListIterator<ShippingStatus> ship(&package); might not work (or isn't what you want) is likely because your iterator's constructor only takes a pointer. Let's adjust the iterator class to support references directly:
template <typename T> class DoublyLinkedListIterator { private: DoublyLinkedList<T>* m_list; // We'll still store a pointer internally public: // Constructor that accepts a pointer (kept for backward compatibility) DoublyLinkedListIterator(DoublyLinkedList<T>* list) : m_list(list) {} // Overload with a reference parameter (this is what you need!) DoublyLinkedListIterator(DoublyLinkedList<T>& list) : m_list(&list) {} // ... Rest of your iterator methods (moveNext(), isEnd(), getCurrent(), etc.) };
Now you can declare your iterator cleanly with a reference:
DoublyLinkedList<ShippingStatus> package; DoublyLinkedListIterator<ShippingStatus> ship(package); // Uses the reference constructor
2. Stop the Iterator from Resetting on Function Calls
The problem with declaring the iterator inside a function is that it gets destroyed and reinitialized every time the function runs. Here are a few solid fixes:
Option 1: Make the Iterator a Class Member
If your package list is part of a class, simply declare the iterator as a member of the same class and initialize it in the constructor. This way, it stays alive for the lifetime of the class instance:
class ShipmentTracker { private: DoublyLinkedList<ShippingStatus> m_packageList; DoublyLinkedListIterator<ShippingStatus> m_shipIterator; public: // Initialize the iterator with a reference to our list in the constructor ShipmentTracker() : m_shipIterator(m_packageList) {} void processNextShipment() { // Use m_shipIterator here—its state is preserved between calls! if (!m_shipIterator.isEnd()) { ShippingStatus current = m_shipIterator.getCurrent(); // ... Process status m_shipIterator.moveNext(); } } };
Option 2: Use a Static Iterator (Careful!)
If you can't use a class, you can mark the iterator as static inside your function. This makes it initialize only once, retaining its state across function calls. Just be cautious with this in multi-threaded code:
void processShipments() { static DoublyLinkedList<ShippingStatus> package; static DoublyLinkedListIterator<ShippingStatus> ship(package); // Only initialized once // Use ship here—state persists between function calls if (!ship.isEnd()) { // ... Do work ship.moveNext(); } }
Option 3: Pass the Iterator as a Parameter
If you need to use the iterator across multiple functions, pass it by reference to each function instead of creating a new one each time:
void updateShipmentStatus(DoublyLinkedListIterator<ShippingStatus>& ship) { if (!ship.isEnd()) { ship.getCurrent().setStatus(Status::InTransit); ship.moveNext(); } } int main() { DoublyLinkedList<ShippingStatus> package; DoublyLinkedListIterator<ShippingStatus> ship(package); // Populate package list... updateShipmentStatus(ship); // Iterator state is retained after this call updateShipmentStatus(ship); // Continues from where it left off return 0; }
Wrap-Up
First, adjust your iterator class to accept a reference, then pick the option that fits your code structure best—class members are usually the cleanest for long-lived state, while static or parameter-passing work for simpler scenarios.
内容的提问来源于stack exchange,提问作者lawgik

