使用操作符重载打印单链表

Using operator overload to print Singly Linked List

本文关键字:链表 单链表 打印 操作符 重载      更新时间:2023-10-16

我在弄清楚如何使用操作符重载打印单链表时遇到了很多麻烦。每当我尝试编译时,我得到错误说'->'不是SLinkedList的重载成员,错误说'next'不是SLinkedList的成员。这是我目前所知道的。

template <typename E> class SLinkedList;
template <typename E> class SNode;
template <typename E>
ostream& operator<< (ostream& out, const SLinkedList<E>& v);
template <typename E> 
class SNode {
private:
    E elem;
    SNode<E>* next;
    friend class SLinkedList<E>;
};
template <typename E> 
class SLinkedList {
public:
    SLinkedList();
    ~SLinkedList();
    bool empty() const;
    const E& front() const;
    void addFront(const E& e);
    void removeFront();
    int getSize();
private:
    SNode<E>* head;
    int size;
};
template <typename E>
ostream& operator <<(ostream& out, SLinkedList<E>& v) {
    for (SNode<E>* n = v->next; n != NULL; n = n->next)
    {
        out << n->elem;
    }
    return out;
    }
//END OF CLASS METHOD DEFINITIONS
float randGen() {
    float num = (rand() % 1000) + 1;
    num = num / 1000;
    return num;
}
void main() {
    SLinkedList<float> lst;
    int lstElems = 10;
    for (int i = 0; i < lstElems; i++) {
        lst.addFront(randGen());
    }
    cout << lst << endl;

    system("pause");
}

一,v是一个引用,而不是一个指针,这就是为什么编译器抱怨->没有被重载。

第二,next不是SLinkedList的成员,它是SNode的成员。

第三,需要提供遍历链表的公共方法。至少有一个方法返回head .

#include <iostream>
#include <cstdlib>
#include <list>
using namespace std;
template <typename E> class SLinkedList;
template <typename E> class SNode;
template <typename E>
ostream& operator<< (ostream& out, const SLinkedList<E>& v);
template <typename E>
class SNode {
private:
    E elem;
    SNode<E>* next;
    friend class SLinkedList<E>;
};
template <typename E>
class SLinkedList {
public:
    class Iterator {
    public:
        const E &operator * () {
            return curNode->elem;
        }
        Iterator &operator ++ () {
            this->curNode = this->curNode->next;
            return *this;
        }
        bool operator == (const Iterator &o) const {
            if (this == &o) return true;
            return this->curNode == o.curNode;
        }
        bool operator != (const Iterator &o) const {
            return !(*this == o);
        }
        Iterator(SNode<E> *n) : curNode(n) {}
    private:
        SNode<E> *curNode;
    };
    SLinkedList() : head(nullptr) {}
    ~SLinkedList() {
        while (head != nullptr) {
            auto next = head->next;
            delete head;
            head = next;
        }
    }
    bool empty() const;
    const E& front() const;
    void addFront(const E& e) {
        auto p = new SNode<E>;
        p->elem = e;
        p->next = head;
        head = p;
    }
    void removeFront();
    int getSize();
    Iterator begin() const {
        return Iterator(head);
    }
    Iterator end() const {
        return Iterator(nullptr);
    }
private:
    SNode<E>* head;
    int size;
};
template <typename E>
ostream& operator <<(ostream& out, const SLinkedList<E>& v) {
    for (auto i = v.begin(); i != v.end(); ++i)
    {
        out << *i;
    }
    return out;
}
//END OF CLASS METHOD DEFINITIONS
float randGen() {
    float num = (rand() % 1000) + 1;
    num = num / 1000;
    return num;
}
void main() {
    SLinkedList<float> lst;
    int lstElems = 10;
    for (int i = 0; i < lstElems; i++) {
        lst.addFront(randGen());
    }
    cout << lst << endl;
    system("pause");
}