友元函数无法访问私有数据成员 (c++)

Friend function cannot access private data member (c++)

本文关键字:数据成员 c++ 函数 访问 友元      更新时间:2023-10-16

我搜索了许多不同的问题,但找不到与我的特定问题相匹配的解决方案。我有一个队列的头文件:

#ifndef HEADERFILE
#define HEADERFILE
#include <iostream>
#include <vector>
using namespace std;
template<class myType>
class Queue{
private:
int size;
vector<myType> list; 
public:
Queue(int);
void Enqueue(myType);
myType Dequeue();
myType PeekFront();
int length();
void empty();
myType Index(int);
friend void printArray();
};
#endif

有问题的问题是针对friend void printArray.这是实现文件:

#include "queueTask1.h"
#include <vector>
#include <iostream>
using namespace std;
(Other function implementations)
void printArray(){
for (int i = 0; i < list.size(); i++){
cout << list.at(i) << ", ";
}
cout << endl;
}

尝试运行此命令时的错误指出

"列表"未在此范围内声明

但是,它是在头文件中声明的,所有其他成员函数都可以正常工作。由于某种原因,printArray找不到私有数据成员list,即使它应该是一个友元函数。

list是非静态数据成员。 这意味着每个对象都有一个list。 由于它是依赖于对象的,因此您需要一个对象来访问其list。 最简单的方法是将对象传递给函数,例如

// forward declare the function, unless you want to define the function inside the class
template<class ElementType>
friend void printArray(const Queue<ElementType>&);
template<class myType>
class Queue{
//...
// declare the friendship
template<class ElementType>
friend void printArray(const Queue<ElementType>&);
//...
};
// define the function
template<class ElementType>
void printArray(const Queue<ElementType>& q)
{
for (int i = 0; i < q.list.size(); i++){
cout << q.list.at(i) << ", ";
}
cout << endl;
}   

您还需要将Queue的实现移动到头文件中,因为它是一个 temaplte。 有关更多内容,请参阅:为什么模板只能在头文件中实现?

声明非常好,但是您正在处理此类的哪个实例? 如果您有object.list,则可以访问list,但只是list不引用任何内容。传递类的实例,并使用它来访问list

像这样:

void printArray(const Queue& object)

您需要将类实例传递到printArray()然后才能访问该实例的私有成员。 否则,printArray()不知道要使用哪个实例。

void printArray(Queue &myQueue){
for (int i = 0; i < myQueue.list.size(); i++){
cout << myQueue.list.at(i) << ", ";
}
cout << endl;
}

我自己,我会这样做:

template<class myType>
class Queue{
// snip ...
public:
// snip ...
template<class F>
friend void foreach_element(Queue& q, F&& f) {
for(auto&&e:list) f(e);
}
template<class F>
friend void foreach_element(Queue const& q, F&& f) {
for(auto&&e:list) f(e);
}
};
template<class myType>
void printArray(Queue<myType> const& q) {
foreach_element(q, [](auto&& e){ std::cout << e << ","; } );
std::cout << std::endl;
}

请注意,printArray的实现必须放在标头中,因为它是一个模板函数。

我暴露了foreach_element来了解元素,然后printArray成为一个使用它的非朋友。