C++模板化的朋友类

C++ Templated Friend Classes

本文关键字:朋友 C++      更新时间:2023-10-16

我正在用 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

我想让 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