2014-11-13 4 views
0

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

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 

ответ

1

Я хочу OListIterator иметь доступ к "Node" структуры внутри класса списка.

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

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.