简体   繁体   中英

C++ Templated Friend Classes

I am working in c++. I'm attempting to make my own iterator for a templated linked list class (without using the STL), but I seem to have trouble using "friends." I want to OListIterator to have access to the "Node" struct within the list class. If anyone could help it would be greatly appreciated!

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

List:

#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

I want to OListIterator to have access to the "Node" struct within the list class.

For this, you need to forward-declare the iterator class:

template<typename T> OListIterator;

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

Alternatively, you can use a template friend declaration, but then any OListIterator type has access to any list type:

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

Here is a more verbose but unrelated-to-your-code example:

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);
}

The constructor of the Iterator class prints the private member somePrivateMember , whose value is 1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM