【问题标题】:How to implement iterator design pattern on C++?如何在 C++ 上实现迭代器设计模式?
【发布时间】:2020-08-13 04:53:21
【问题描述】:

我很好奇如何像 STL 在堆栈 ADT 中那样实现迭代器模式。

#include <iostream>
#include <vector>

int main() {
    std::vector<char> v = { 'a', 'b', 'c', 'd', 'e', 'f'};

    std::vector<char>::iterator it = v.begin();

    while(it != v.end()) {
        std::cout << *it << "->";
        ++it;
    }

    std::cout << "\n";

    return 0;
}

输出

a->b->c->d->e->f->

到目前为止,我已经实现了以下代码

#include <iostream>
#include <memory>

template<class T>class Node {
private:
    T data = 0;
    std::shared_ptr<Node<T>> next_node = nullptr;

public:
    Node(T data = 0, std::shared_ptr<Node<T>> next_node = nullptr)
        : data(data), next_node(next_node)
    {
        std::cout << "created node[" << data << "]\n";
    }

    ~Node() {
        std::cout << "deleted node[" << data << "]\n";
    }

    // getters and setters

    T getData() const {
        return this->data;
    }

    std::shared_ptr<Node<T>> getNextNode() const {
        return this->next_node;
    }

    void setData(T value) {
        this->data = value;
    }

    void setNextNode(std::shared_ptr<Node<T>> node) {
        this->next_node = node;
    }
};

template<class T>std::ostream& operator<<(std::ostream& o, const std::shared_ptr<Node<T>> node) {
    return o << "node["<< node->getData() <<"]-> ";
}

template<class T>class Stack {
private:
    std::shared_ptr<Node<T>> top = nullptr;

public:
    Stack()
        : top(nullptr)
    { /* empty */ }

    ~Stack() { /* empty */ }

    void push(T value) {
        if(!top) {
            top = std::shared_ptr<Node<T>> (new Node<T>(value));
        } else {
            top = std::shared_ptr<Node<T>> (new Node<T>(value, top));
        }
    }

    void display() {
        if(!top) {
            std::cout << "display::The stack is empty.\n";
        } else {
            std::shared_ptr<Node<T>> p = top;

            while(p) {
                std::cout << p;
                p = p->getNextNode();
            }

            std::cout << "\n";
        }
    }

    class Iterator {
    private:
        std::shared_ptr<Node<T>> node;

    public:
        Iterator(std::shared_ptr<Node<T>> node)
            : node(node)
        { /* empty */ }

        bool hasMore() {
            return node->getNextNode() != nullptr;
        }

        Iterator getNext() {
            return Iterator(node->getNextNode());
        }

        int getData() {
            return node->getData();
        }
    };

    Iterator begin() const {
        return Iterator(top);
    }

    Iterator getIterator() {
        Iterator it = Iterator(top);

        return it;
    }
};

int main() {
    Stack<char> stack;

    for(char i = 'a'; i < 'f'; ++i) {
        stack.push(i);
    }

    Stack<char>::Iterator it = stack.begin();

    while(it.hasMore()) {
        std::cout << it.getData() << "->";
        it = it.getNext();
    }

    std::cout << "\n";

    return 0;
}

输出:

created node[a]
created node[b]
created node[c]
created node[d]
created node[e]
101->100->99->98->
deleted node[e]
deleted node[d]
deleted node[c]
deleted node[b]
deleted node[a]

我的问题是如何为 Iterator 类实现嵌套模板检测,正如您所见,预期的输出是 char 类型,而我得到的是整数。

有人能帮我理解这是如何在 STL 中实现的,以及如何在 ADT 中实现吗?

谢谢!!!

【问题讨论】:

  • 函数Iterator::getData 返回一个int。您是否正在寻找类似auto getData() { return node-&gt;getData(); } 的功能
  • 实例化 Stack&lt;std::string&gt; 并让编译错误引导您。
  • 感谢您的快速回答,我看到了我的错误...我只是将以下int getData() { return node-&gt;getData(); } 更改为T getData() { return node-&gt;getData(); },现在可以正常工作了!!!谢谢!!!

标签: c++ design-patterns iterator


【解决方案1】:

感谢 cmets 我能够解决我在 int getData() { return node-&gt;getData(); } 上返回错误数据类型的问题我只需将 int 类型更改为 T 类型,一切正常!

还将hasMore 方法更改为bool hasMore() { return node != nullptr; }

#include <iostream>
#include <memory>

template<class T>class Node {
private:
    T data = 0;
    std::shared_ptr<Node<T>> next_node = nullptr;

public:
    Node(T data = 0, std::shared_ptr<Node<T>> next_node = nullptr)
        : data(data), next_node(next_node)
    {
        std::cout << "created node[" << data << "]\n";
    }

    ~Node() {
        std::cout << "deleted node[" << data << "]\n";
    }

    // getters and setters

    T getData() const {
        return this->data;
    }

    std::shared_ptr<Node<T>> getNextNode() const {
        return this->next_node;
    }

    void setData(T value) {
        this->data = value;
    }

    void setNextNode(std::shared_ptr<Node<T>> node) {
        this->next_node = node;
    }
};

template<class T>std::ostream& operator<<(std::ostream& o, const std::shared_ptr<Node<T>> node) {
    return o << "node["<< node->getData() <<"]-> ";
}

template<class T>class Stack {
private:
    std::shared_ptr<Node<T>> top = nullptr;

public:
    Stack()
        : top(nullptr)
    { /* empty */ }

    ~Stack() { /* empty */ }

    void push(T value) {
        if(!top) {
            top = std::shared_ptr<Node<T>> (new Node<T>(value));
        } else {
            top = std::shared_ptr<Node<T>> (new Node<T>(value, top));
        }
    }

    void display() {
        if(!top) {
            std::cout << "display::The stack is empty.\n";
        } else {
            std::shared_ptr<Node<T>> p = top;

            while(p) {
                std::cout << p;
                p = p->getNextNode();
            }

            std::cout << "\n";
        }
    }

    class Iterator {
    private:
        std::shared_ptr<Node<T>> node;

    public:
        Iterator(std::shared_ptr<Node<T>> node)
            : node(node)
        { /* empty */ }

        bool hasMore() {
            return node != nullptr;
        }

        Iterator getNext() {
            return Iterator(node->getNextNode());
        }

        T getData() {
            return node->getData();
        }
    };

    Iterator begin() const {
        return Iterator(top);
    }

    Iterator getIterator() {
        Iterator it = Iterator(top);

        return it;
    }
};

int main() {
    Stack<char> stack;

    for(char i = 'a'; i < 'f'; ++i) {
        stack.push(i);
    }

    Stack<char>::Iterator it = stack.begin();

    while(it.hasMore()) {
        std::cout << it.getData() << "->";
        it = it.getNext();
    }

    std::cout << "\n";

    return 0;
}

输出

created node[a]
created node[b]
created node[c]
created node[d]
created node[e]
e->d->c->b->a->
deleted node[e]
deleted node[d]
deleted node[c]
deleted node[b]
deleted node[a]

【讨论】:

    猜你喜欢
    • 2021-01-19
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2014-06-06
    • 2023-03-18
    • 2020-01-17
    相关资源
    最近更新 更多