首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

設計模式實作系列(十八):Iterator 迭代器模式 - 統一遍歷介面隔離演算法與容器

     編輯:關於C++

模式意圖

提供一種方法順序訪問一個聚合物件中各個元素,而又不需暴露該物件的內部表示。

UML 結構圖

Iterator Pattern UML

核心解析:STL 的基石

Iterator 是多數 C++ 開發者接觸的第一個設計模式(STL 容器皆內建迭代器)。其精髓在於:

  • 規範化介面: 所有迭代器遵循統一規範(value_type, pointer, reference, ++, ==, * 等),使演算法能通用於任何符合規範的容器。
  • 職責分離: 遍歷邏輯封裝於具體 Iterator 類別,容器只需提供 CreateIterator()。演算法不關心容器底層是陣列、鏈表還是樹。
  • 多態遍歷: 客戶端持有抽象 Iterator*,執行期綁定具體迭代器,實現「演算法與容器獨立變化」。

C++ 完整實作

1. Iterator.h

#ifndef ITERATOR_H
#define ITERATOR_H

typedef int DATA;

class Iterator;
class Aggregate;

// 聚合抽象基類
class Aggregate {
public:
    virtual ~Aggregate() {}
    virtual Iterator* CreateIterator(Aggregate* pAggregate) = 0;
    virtual int GetSize() = 0;
    virtual DATA GetItem(int nIndex) = 0;
};

// 迭代器抽象基類(規範介面)
class Iterator {
public:
    virtual ~Iterator() {}
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual bool IsDone() = 0;
    virtual DATA CurrentItem() = 0;
};

// 具體聚合:陣列實作
class ConcreteAggregate : public Aggregate {
public:
    ConcreteAggregate(int nSize);
    virtual ~ConcreteAggregate();
    virtual Iterator* CreateIterator(Aggregate* pAggregate);
    virtual int GetSize();
    virtual DATA GetItem(int nIndex);
private:
    int m_nSize;
    DATA* m_pData;
};

// 具體迭代器:遍歷 ConcreteAggregate
class ConcreteIterator : public Iterator {
public:
    ConcreteIterator(Aggregate* pAggregate);
    virtual ~ConcreteIterator() {}
    virtual void First();
    virtual void Next();
    virtual bool IsDone();
    virtual DATA CurrentItem();
private:
    Aggregate* m_pConcreteAggregate;
    int m_nIndex;
};

#endif

2. Iterator.cpp

#include <iostream>
#include "Iterator.h"

ConcreteAggregate::ConcreteAggregate(int nSize) : m_nSize(nSize), m_pData(nullptr) {
    m_pData = new DATA[m_nSize];
    for (int i = 0; i < nSize; ++i) m_pData[i] = i;
}
ConcreteAggregate::~ConcreteAggregate() {
    delete[] m_pData; m_pData = nullptr;
}

Iterator* ConcreteAggregate::CreateIterator(Aggregate* pAggregate) {
    return new ConcreteIterator(this);
}
int ConcreteAggregate::GetSize() { return m_nSize; }
DATA ConcreteAggregate::GetItem(int nIndex) {
    return (nIndex < m_nSize) ? m_pData[nIndex] : -1;
}

ConcreteIterator::ConcreteIterator(Aggregate* pAggregate) : m_pConcreteAggregate(pAggregate), m_nIndex(0) {}

void ConcreteIterator::First() { m_nIndex = 0; }
void ConcreteIterator::Next() {
    if (m_nIndex < m_pConcreteAggregate->GetSize()) ++m_nIndex;
}
bool ConcreteIterator::IsDone() {
    return m_nIndex == m_pConcreteAggregate->GetSize();
}
DATA ConcreteIterator::CurrentItem() {
    return m_pConcreteAggregate->GetItem(m_nIndex);
}

3. Main.cpp

#include "Iterator.h"
#include <iostream>

int main() {
    Aggregate* pAggregate = new ConcreteAggregate(4);
    Iterator* pIterator = new ConcreteIterator(pAggregate);

    for (; !pIterator->IsDone(); pIterator->Next())
        std::cout << pIterator->CurrentItem() << std::endl; // 輸出 0 1 2 3

    delete pIterator;
    delete pAggregate;
    return 0;
}

現代 C++ 的演進

C++11 起,範圍ベース for 循環(for (auto& x : container))隱式使用 begin()/end(),本質仍是 Iterator 模式。自製容器只需提供符合標準的迭代器型別,即可無縫融入 STL 生態。

適用場景

  • 自訂資料結構(樹、圖、資料庫游標)需支援標準遍歷語法。
  • 多種遍歷策略(前序/後序、過濾、投影)共存時,各自實作為獨立 Iterator 類別。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved