【问题标题】:Why can't my friend class access a private member?为什么我的朋友班不能访问私人会员?
【发布时间】:2018-10-23 01:03:36
【问题描述】:

我认为当一个类声明一个朋友类时,朋友可以访问声明者的私有成员?好像不是这样,或者我做错了什么。我正在尝试访问 OULinkedList 中的“第一个”或“最后一个”。当我尝试使用“第一个”或“最后一个”时,我收到“未在此范围内声明”错误。

我需要访问“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;
    }
}

【问题讨论】:

标签: c++ pointers linked-list enumeration friend


【解决方案1】:
  1. 您发布的描述表明您的代码编译成功。在这种情况下,您在问题标题中谈论的是哪些私人访问问题? C++ 中的访问控制是一个纯粹的编译时概念。如果您的代码编译成功,那么私有访问没有问题。

  2. 您的类模板OULinkedListEnumeratorOULinkedList 类模板中的嵌套类模板。就像任何嵌套类一样,它应该可以完全访问封闭类模板 OULinkedList 的私​​有成员,而无需任何朋友声明。

  3. 以防万一,当您为未知实体进行友元声明时,该实体被假定为封闭命名空间范围的成员。所以你的

    template <typename F>
    friend class OULinkedListEnumerator;
    

    引用全局类模板::OULinkedListEnumerator 并使其成为朋友。稍后您声明一个嵌套类模板OULinkedList::OULinkedListEnumerator。这是一个完全不同的类模板。它不是朋友。 (但没必要,见 2)。

  4. 不允许在嵌套模板声明中重复使用模板参数名称。您必须将嵌套模板参数的名称从 T 更改为其他名称。事实上,令我惊讶的是,您能够在没有首先遇到此参数命名问题的情况下将代码编译到所谓的“访问问题”。

【讨论】:

  • 所以我犯了一个错误,并没有澄清我在尝试访问“第一个”或“最后一个”时收到的投诉——它是“未在此范围内声明”并且我没有包括在代码中的任何地方使用“first”或“last”。我将朋友类声明更改为“F”而不是“T”。这可能是问题的一部分吗?如果我在声明中将其声明为“F”,那么定义是否也必须在 OULinkedListEnumerator 中为 F?
  • @Adam G:我看到你在朋友声明中将T更改为F,但在OULinkedListEnumerator的实际声明中仍然使用T。这怎么可能?您的 OULinkedListEnumerator 实际上是 nested 类模板吗?还是您只是忘记了在此处发布的代码中定义 OULinkedList 之后的结束 };?请发布真实代码,而不是一些虚构的草图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多