You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为抽象基类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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:43:16