[英]Why can't my friend class access a private member?
I thought when a class declared a friend class, that friends could access the declarer's private members?我想当一个类声明一个朋友类时,朋友可以访问声明者的私有成员? This doesn't seem to be the case, or I've done something wrong.
情况似乎并非如此,或者我做错了什么。 I'm trying to access "first" or "last" in OULinkedList.
我正在尝试访问 OULinkedList 中的“第一个”或“最后一个”。 When I try to use "first" or "last" I get a "not declared in this scope" error.
当我尝试使用“第一个”或“最后一个”时,出现“未在此范围内声明”错误。
I need access to "first" because without it my next function will never return the first value of the linked list and I'm not sure how else to do it.我需要访问“first”,因为没有它我的下一个函数将永远不会返回链表的第一个值,我不知道怎么做。
For example if I just want to print out the objects in my list, the following while loop always skips the first object.例如,如果我只想打印出列表中的对象,那么下面的 while 循环总是会跳过第一个对象。
while(enumerator.hasNext()){
cout << enumerator.next();
}
Which is obviously not what I want.这显然不是我想要的。
#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;
}
}
The description you posted suggest that your code compiled successfully.您发布的描述表明您的代码编译成功。 In that case what private access problems are you talking about in your question's title?
在这种情况下,您在问题标题中谈论的是什么私人访问问题? Access control in C++ is a purely compile-time concept.
C++ 中的访问控制是一个纯粹的编译时概念。 If your code compiled sucessfully, then it has no problems with private access.
如果您的代码编译成功,那么私有访问就没有问题。
Your class template OULinkedListEnumerator
is a nested class template in OULinkedList
class template.您的类模板
OULinkedListEnumerator
是OULinkedList
类模板中的嵌套类模板。 Just like any nested class, it is supposed to have full access to private members of the enclosing class template OULinkedList
without any need for any friend declarations.就像任何嵌套类一样,它应该拥有对封闭类模板
OULinkedList
私有成员的完全访问权限,而无需OULinkedList
声明。
Just in case, when you make a friend declaration for a yet-unknown entity, the entity is assumed to be a member of the enclosing namespace scope.以防万一,当您为未知实体进行友元声明时,假定该实体是封闭命名空间范围的成员。 So your
所以你的
template <typename F> friend class OULinkedListEnumerator;
refers to a global class template ::OULinkedListEnumerator
and makes it a friend.引用全局类模板
::OULinkedListEnumerator
并使其成为朋友。 Later you declare a nested class template OULinkedList::OULinkedListEnumerator
.稍后您声明一个嵌套类模板
OULinkedList::OULinkedListEnumerator
。 This is a completely different class template.这是一个完全不同的类模板。 It is not a friend.
它不是朋友。 (But it doesn't need to be, see 2).
(但它不一定是,见 2)。
You are not allowed to reuse template parameter names in nested template declarations.不允许在嵌套模板声明中重复使用模板参数名称。 You have to change the name of the nested template parameter from
T
to something else.您必须将嵌套模板参数的名称从
T
更改为其他名称。 In fact, I'm surprised you managed to compile the code to the point of some alleged "access problem" without hitting this parameter naming issue first.事实上,我很惊讶你设法将代码编译到一些所谓的“访问问题”点,而没有先解决这个参数命名问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.