C ++ шаблонные классы друзей

0

Я работаю в c++. Я пытаюсь сделать свой собственный итератор для шаблона связанного списка (без использования STL), но у меня, похоже, проблемы с использованием "друзей". Я хочу, чтобы OListIterator имел доступ к структуре "Узла" в классе списка. Если бы кто-нибудь мог помочь, это было бы очень признательно!

OListIterator:

#ifndef pg6ec_OListIterator_h
#define pg6ec_OListIterator_h
#include "OList.h"
template <typename T>
class OListIterator
{
private:
    T * value;
    T * next;

public:
    OListIterator()
    {}
    void setValue(T & val, T & n)
    {
        value = &val;
        next = &n;
    }

    int operator*()
    {
        return *value;
    }

    bool operator==(OListIterator<T> other)
    {
        return value == other.value && next == other.next;
    }

    bool operator!=(OListIterator<T> other)
    {
        return value != other.value && next != other.next;
    }

    void operator+=(int x)
    {

    }
};

#endif

Список:

#ifndef pg6OList_OListBlah_h
#define pg6OList_OListBlah_h

#include <stdio.h>
#include <stdlib.h>
#include "OListIterator.h"

template <typename T>
class list
{
private:
    typedef struct node
    {
        T value;
        struct node * next;
    }Node;
    Node * root;


public:
    list()
    {
        root = NULL;
    }

    list(const list & other)
    {
        Node * temp = other.returnRoot();
        Node * currSpot = NULL;
        root = new Node;
        root->value = temp->value;
        currSpot = root;
        temp = temp->next;
        while (temp)
        {
            currSpot->next = new Node;
            currSpot = currSpot->next;
            currSpot->value = temp->value;
            temp = temp->next;
        }
    }

    ~list()
    {
        clear();
    };


    void clear()
    {
        Node * delNode = root;
        while (delNode)
        {
            root = root->next;
            delete delNode;
            delNode = root;
        }
        delete root;
    };

    Node * returnRoot() const
    {
        return this->root;
    }

    int size()
    {
        int ans = 0;
        if (root == NULL)
        {
            return ans;
        }
        Node * top = root;
        while (top)
        {
            ans++;
            top = top->next;
        }
        return ans;
    }


    bool insert(T & item)
    {
        if (root == NULL)
        {
            root = new Node;
            root->value = item;
            return true;
        }

        else
        {
            Node * curr = root;
            Node * prev = NULL;
            while (curr)
            {
                if ( curr->value > item )
                {
                    Node * insertion = new Node;
                    insertion->value = item;
                    if (prev)
                    {
                        insertion->next = curr;
                        prev->next = insertion;
                    }
                    else
                    {
                        root = insertion;
                        root->next = curr;
                    }
                    return true;
                }
                else if ( curr->value == item )
                {
                    Node * insertion = new Node;
                    insertion->value = item;
                    insertion->next = curr->next;
                    curr->next = insertion;
                    return true;
                }

                prev = curr;
                if (curr->next)
                {
                    curr = curr->next;
                }
                else if ( curr->next == NULL )
                {
                    curr->next = new Node;
                    curr->next->next = NULL;
                    curr->next->value = item;
                    return true;
                }
            }
        }
        return false;
    }


    T get(int x)
    {
        T ans = root->value;
        if (x > size() || x < 0)
        {
            return ans;
        }
        Node * curr = root;
        for (int i = 0; i < size(); i++)
        {
            if (i == x)
            {
                ans = curr->value;
                break;
            }
            curr = curr->next;
        }
        return ans;
    }


    int count(T base)
    {
        int num = 0;
        Node * curr = root;
        while (curr)
        {
            if (curr->value == base)
            {
                num++;
            }
            curr = curr->next;
        }
        return num;
    }


    bool remove(T base)
    {
        Node * curr = root;
        Node * prev = NULL;
        if (root->value == base)
        {
            delete this->root;
            root = root->next;
            return true;
        }
        while (curr)
        {
            if (curr->value == base)
            {
                Node * temp = new Node;
                if (curr->next)
                {
                    T val = curr->next->value;
                    temp->value = val;
                    temp->next = curr->next->next;
                }
                delete curr;
                delete curr->next;
                prev->next = temp;
                return true;
            }
            prev = curr;
            curr = curr->next;
        }
        return false;
    }


    void uniquify()
    {
        Node * curr = root;
        Node * next = root->next;
        while (curr)
        {
            while (next && curr->value == next->value)
            {
                Node * temp = new Node;
                if (next->next)
                {
                    T val = next->next->value;
                    temp->value = val;
                    temp->next = next->next->next;
                    delete next;
                    delete next->next;
                    curr->next = temp;
                    next = curr->next;
                }
                else
                {
                    delete temp;
                    delete temp->next;
                    curr->next = NULL;
                    delete next;
                    delete next->next;
                    break;
                }
            }

            curr = curr->next;
            if (curr)
                next = curr->next;
        }
    }

    OListIterator<T> begin()
    {
        OListIterator<T> it;
        it.setValue(root->value, root->next->value);
        return it;
    }

    OListIterator<T> end()
    {
        Node * curr = root;
        for (int i = 0; i < size(); i++)
        {
            curr = curr->next;
        }
        OListIterator<T> it;
        it.setValue(curr->value);
        return it;
    }
};
#endif
Теги:
list

1 ответ

1
Лучший ответ

Я хочу, чтобы OListIterator имел доступ к структуре "Узла" в классе списка.

Для этого вам нужно переслать-объявить класс итератора:

template<typename T> OListIterator;

template <typename T>
class list
{
    friend class OListIterator<T>;
    //... the rest
}

Кроме того, вы можете использовать объявление шаблона друга, но тогда любой тип OListIterator имеет доступ к любому типу list:

template <typename T>
class list
{
    template<typename U> friend class OListIterator;
    //... the rest
} 

Ниже приведен более подробный, но не связанный с вашим кодом пример:

template<typename T> struct Iterator;

template<typename T>
struct List
{
    friend struct Iterator<T>;
    List(T i) : somePrivateMember(i) {}

private:
    T somePrivateMember;
};


template<typename T>
struct Iterator
{
    Iterator(List<T> const& list) {std::cout<<list.somePrivateMember<<std::endl;}
};



int main()
{
    List<int> list(1);

    Iterator<int> iterator(list);
}

Конструктор класса Iterator печатает частный член somePrivateMember, значение которого равно 1.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню