自定义列表实现迭代器无法访问最后一个元素(c ++)

时间:2016-03-11 16:48:03

标签: c++ list iterator

我正在为个人项目实施自定义列表&我似乎无法使用迭代器访问最后一个元素。

它基本上是一个扁平的双向链表(带有下一个和前一个节点指针)。

expression.hpp

#ifndef TPP_EXPRESSION_HPP
#define TPP_EXPRESSION_HPP

#include <cstddef>
#include <globals.hpp>
#include "node.hpp"
#include "iterator.hpp"
#include <iostream>

namespace tpp {
namespace expression {
class Expression {
    std::size_t _size;
    Node* left;
    Node* right;

public:
    void print() {
        Node* node = left;
        while (node != nullptr) {
            std::cout << node->value << "\t";
            node = node->next;
        }
    }

    void append(byte val) {
        Node* node = new Node(val);
        if (right != nullptr) {
            Node* tmp = right;
            tmp->next = node;
            right = node;
            right->prev = tmp;
        } else {
            left = right = node;
        }
        _size++;
    }

    Iterator begin() {
        std::cout << "Left: " << left->value << std::endl;
        return Iterator(left);
    }

    const ConstIterator cbegin() const {
        return ConstIterator(left);
    }

    Iterator end() {
        std::cout << "Right: " << right->value << std::endl;
        return Iterator(right);
    }

    const ConstIterator cend() const {
        return ConstIterator(right);
    }

    bool is_empty() {
        return _size == 0;
    }

    std::size_t size() {
        return _size;
    }

    Expression() : _size(0), left(nullptr), right(nullptr) {
    }

    ~Expression() {
        Node* node = right;
        while (node != nullptr) {
            Node* old_back = node;
            node = node->prev;
            delete old_back;
        }
        left = nullptr;
        right = nullptr;
    }
};
} // expression
} // tpp
#endif //TPP_EXPRESSION_HPP

iterator.hpp

#ifndef TPP_EXPRESSION_ITERATOR_HPP
#define TPP_EXPRESSION_ITERATOR_HPP

#include <globals.hpp>
#include "node.hpp"
#include <iostream>

namespace tpp {
namespace expression {

class Iterator {
    Node* node;
public:
    Iterator(Node* ptr) : node(ptr) {}
    Iterator(const Iterator& rhs) : node(rhs.node) {}
    Iterator& operator++() { std::cout << "Current: " << node->value << std::endl; node = node->next; std::cout << "Now: " << node->value << std::endl;return *this; }
    Iterator& operator--() { node = node->prev; return *this; }
    bool operator!=(const Iterator& rhs) { bool stats = node != rhs.node; std::cout << (stats ? "Not equal" : "Equal") << std::endl;  return stats; }
    bool operator==(const Iterator& rhs) { return node == rhs.node; }
    byte& operator*() { std::cout << "Dereferencing " << node->value << std::endl; return node->value; }
};

class ConstIterator {
    const Node* node;
public:
    ConstIterator(const Node* ptr) : node(ptr) {}
    ConstIterator(const ConstIterator& rhs) : node(rhs.node) {}
    ConstIterator& operator++() { node = node->next; return *this; }
    ConstIterator& operator--() { node = node->prev; return *this; }
    bool operator!=(const ConstIterator& rhs) { return node != rhs.node; }
    bool operator==(const ConstIterator& rhs) { return node == rhs.node; }
    const byte& operator*() const { return node->value; }
};
} // expression
} // tpp
#endif //TPP_EXPRESSION_ITERATOR_HPP

node.hpp

#ifndef TPP_EXPRESSION_NODE_HPP
#define TPP_EXPRESSION_NODE_HPP
#include <globals.hpp>

namespace tpp {
namespace expression {
struct Node {
    Node* prev;
    Node* next;
    byte value;
    Node(byte value) : value(value), prev(nullptr), next(nullptr) {}
    Node() : value('\0'), prev(nullptr), next(nullptr) {}
};
}
} // tpp
#endif //TPP_EXPRESSION_NODE_HPP

的main.cpp

#include <iostream>
#include <globals.hpp>
#include <expression/include.hpp>

using namespace std;

int main()
{
    tpp::expression::Expression e;
    e.append('0');
    e.append('1');
    e.append('0');
    e.append('1');
    for (auto elem : e) {
        std::cout << elem << std::endl;
    }
    e.print();
}

示例输出

Left: 0
Right: 1
Not equal
Dereferencing 0
0
Current: 0
Now: 1
Not equal
Dereferencing 1
1
Current: 1
Now: 0
Not equal
Dereferencing 0
0
Current: 0
Now: 1
Equal
0       1       0       1

代码很麻烦,在我清理之前我更专注于让它工作。任何帮助都会有用,谢谢。

1 个答案:

答案 0 :(得分:0)

看看print

void print() {
    Node* node = left;
    while (node != nullptr) {
        std::cout << node->value << "\t";
        node = node->next;
    }
}

您将迭代,直到node中有过去的最后一个元素。对于基于范围的for循环也是如此:将无法访问end(..)。所以改变

Iterator end() {
    return Iterator(right);
}

Iterator end() {
    return Iterator(nullptr);
}