Почему мой друг не может получить доступ к личному члену? - PullRequest
0 голосов
/ 23 октября 2018

Я думал, когда класс объявил класс друга, что друзья могут получить доступ к приватным членам декларатора?Похоже, это не так, или я сделал что-то не так.Я пытаюсь получить доступ к «первым» или «последним» в OULinkedList.Когда я пытаюсь использовать «first» или «last», я получаю сообщение об ошибке «not объявляется в этой области».

Мне нужен доступ к «first», потому что без него моя следующая функция никогда не вернет первое значениесвязанный список, и я не уверен, как еще это сделать.

Например, если я просто хочу распечатать объекты в моем списке, следующий цикл while всегда пропускает первый объект.

while(enumerator.hasNext()){
    cout << enumerator.next();
}

Что явно не то, что я хочу.

#include "OULink.h"
#include "Comparator.h"
#include "OULinkedListEnumerator.h"

// OULinkedList stands for Ordered, Unique Linked List. It is a linked list that is always maintained in
// order (based on the comparator provided to it when the list is created) and that only contains unique
// items (that is, duplicates are not allowed)
template <typename T>
class OULinkedList {
    template <typename F>
    friend class OULinkedListEnumerator;
private:
    Comparator<T>* comparator = NULL;               // used to determine list order and item equality
    unsigned long size = 0;                         // actual number of items currently in list
    OULink<T>* first = NULL;                        // pointer to first link in list
    OULink<T>* last = NULL;


template <typename T>
class OULinkedListEnumerator : public Enumerator<T>
{
private:
    OULink<T>* current;
    int firstNode = 0;
public:
    OULinkedListEnumerator(OULink<T>* first);
    bool hasNext() const;
    T next();
    T peek() const;
};

// Implementation goes here
template<typename T>
OULinkedListEnumerator<T>::OULinkedListEnumerator(OULink<T>* first){
    this->current = first;
}
template<typename T>
bool OULinkedListEnumerator<T>::hasNext() const{

    if(this->current->next != NULL){
        return true;
    }else{
        return false;
    }

}
template<typename T>
T OULinkedListEnumerator<T>::next(){


    T successorNode = *this->current->next->data;
    this->current = this->current->next;
    return successorNode;
}
template<typename T>
T OULinkedListEnumerator<T>::peek() const{
    if(current != NULL){
        return *current->data;
    }else{
        throw new ExceptionLinkedListAccess;
    }
}

1 Ответ

0 голосов
/ 23 октября 2018
  1. Описание, которое вы разместили, предполагает успешную компиляцию кода.В таком случае, о каких проблемах с личным доступом вы говорите в заголовке вопроса?Контроль доступа в C ++ является чисто концепцией времени компиляции.Если ваш код скомпилирован успешно, то у него нет проблем с частным доступом.

  2. Ваш шаблон класса OULinkedListEnumerator является вложенным шаблоном класса в OULinkedList шаблоне класса.Как и любой вложенный класс, предполагается, что он имеет полный доступ к закрытым членам шаблона включающего класса OULinkedList без необходимости каких-либо объявлений друзей.

  3. На всякий случай, когда высделайте объявление друга для еще неизвестной сущности, предполагается, что эта сущность является членом охватывающей области пространства имен.Таким образом, ваш

    template <typename F>
    friend class OULinkedListEnumerator;
    

    ссылается на глобальный шаблон класса ::OULinkedListEnumerator и делает его другом.Позже вы объявляете вложенный шаблон класса OULinkedList::OULinkedListEnumerator.Это совершенно другой шаблон класса.Это не друг.(Но это не обязательно, см. 2).

  4. Вы не можете повторно использовать имена параметров шаблона в объявлениях вложенных шаблонов.Вы должны изменить имя параметра вложенного шаблона с T на другое.На самом деле, я удивлен, что вам удалось скомпилировать код до такой степени, что якобы возникла «проблема доступа», не затрагивая сначала проблему именования параметров.

...