如何为抽象基类List实现适配所有派生类的通用Iterator?
实现适配所有List派生类的通用虚拟迭代器方案
核心思路
要实现适配所有List派生类的通用迭代器,需通过桥接模式分离迭代器的对外接口与底层实现:
- 对外暴露统一的
List<T>::Iterator类,内部持有抽象迭代器实现的指针 - 为每个List派生类(如DLL)实现对应具体迭代器实现类,继承自抽象基类
- 利用多态机制,让Iterator自动适配不同容器的迭代逻辑
完整实现代码
1. 抽象基类List及迭代器框架
#include <memory> #include <iostream> template<typename T> class List { public: // 抽象迭代器实现基类,封装核心迭代操作 class IteratorImpl { public: virtual ~IteratorImpl() = default; virtual void increment() = 0; // 对应前置++ virtual void decrement() = 0; // 对应前置-- virtual T& dereference() = 0; // 对应*it virtual bool equals(const IteratorImpl* other) const = 0; // 对应it != other virtual std::unique_ptr<IteratorImpl> clone() const = 0; // 用于迭代器拷贝 }; // 对外的迭代器类,桥接到底层实现 class Iterator { private: std::unique_ptr<IteratorImpl> impl; public: explicit Iterator(std::unique_ptr<IteratorImpl> impl_ptr) : impl(std::move(impl_ptr)) {} // 拷贝构造:克隆底层实现 Iterator(const Iterator& other) : impl(other.impl->clone()) {} Iterator& operator=(const Iterator& other) { if (this != &other) impl = other.impl->clone(); return *this; } // 移动构造/赋值默认生成即可 Iterator(Iterator&&) = default; Iterator& operator=(Iterator&&) = default; // 迭代器运算符重载,转发到底层实现 Iterator& operator++() { impl->increment(); return *this; } Iterator operator++(int) { Iterator temp = *this; impl->increment(); return temp; } Iterator& operator--() { impl->decrement(); return *this; } Iterator operator--(int) { Iterator temp = *this; impl->decrement(); return temp; } T& operator*() { return impl->dereference(); } T* operator->() { return &impl->dereference(); } bool operator!=(const Iterator& other) const { return !impl->equals(other.impl.get()); } bool operator==(const Iterator& other) const { return impl->equals(other.impl.get()); } }; virtual ~List() = default; virtual void push_back(T value) = 0; virtual void push_front(T value) = 0; virtual Iterator begin() = 0; virtual Iterator end() = 0; };
2. 双向链表DLL的实现(含对应迭代器)
template<typename T> class DLL : public List<T> { public: // DLL节点定义 class Node { public: T data; Node* prev; Node* next; explicit Node(T val) : data(std::move(val)), prev(nullptr), next(nullptr) {} }; private: Node* head = nullptr; Node* tail = nullptr; int size = 0; // DLL专属迭代器实现类 class DLLIteratorImpl : public List<T>::IteratorImpl { private: Node* current; public: explicit DLLIteratorImpl(Node* node) : current(node) {} void increment() override { current = current->next; } void decrement() override { current = current->prev; } T& dereference() override { return current->data; } bool equals(const typename List<T>::IteratorImpl* other) const override { const auto* dll_impl = dynamic_cast<const DLLIteratorImpl*>(other); return dll_impl && current == dll_impl->current; } std::unique_ptr<typename List<T>::IteratorImpl> clone() const override { return std::make_unique<DLLIteratorImpl>(current); } }; public: DLL() = default; ~DLL() { // 销毁所有节点 Node* current = head; while (current) { Node* next = current->next; delete current; current = next; } } void push_front(T value) override { Node* new_node = new Node(std::move(value)); if (!head) { head = tail = new_node; } else { new_node->next = head; head->prev = new_node; head = new_node; } size++; } void push_back(T value) override { Node* new_node = new Node(std::move(value)); if (!tail) { head = tail = new_node; } else { tail->next = new_node; new_node->prev = tail; tail = new_node; } size++; } typename List<T>::Iterator begin() override { return typename List<T>::Iterator(std::make_unique<DLLIteratorImpl>(head)); } typename List<T>::Iterator end() override { // end()指向尾节点的下一个位置(nullptr) return typename List<T>::Iterator(std::make_unique<DLLIteratorImpl>(nullptr)); } };
3. 验证需求中的使用场景
int main() { // 场景1:基类指针指向派生类容器,使用基类迭代器 List<List<int>*>* ptr = new DLL<List<int>*>; List<int>* ptr1 = new DLL<int>; for (int i = 0; i < 10; i++) { ptr1->push_back(i); } ptr->push_back(ptr1); List<List<int>*>::Iterator it = ptr->begin(); List<int>::Iterator it1 = ptr1->begin(); // 遍历测试:打印ptr1的元素 for (; it1 != ptr1->end(); ++it1) { std::cout << *it1 << " "; } std::cout << std::endl; // 场景2:直接使用派生类容器的迭代器 DLL<DLL<int>*>* data = new DLL<DLL<int>*>; DLL<DLL<int>*>::Iterator it2 = data->begin(); // 清理内存 delete ptr1; delete ptr; delete data; return 0; }
关键细节说明
- 桥接模式优势:迭代器接口与实现分离,List派生类仅需实现自身的
IteratorImpl,无需修改对外迭代器接口,完美适配多态场景 - 内存安全:用
std::unique_ptr管理迭代器实现的生命周期,clone()方法支持迭代器拷贝,避免内存泄漏 - 类型安全:通过
dynamic_cast在equals()中确保同类型迭代器比较,保证逻辑正确性 - 兼容性:完全支持你需求中的两种使用场景,无论通过基类指针还是直接使用派生类,迭代器均可正常工作
内容的提问来源于stack exchange,提问作者Duy Nguyễn
相关产品推荐
相关产品推荐

