为啥这个友元函数不能访问私有变量?

Posted

技术标签:

【中文标题】为啥这个友元函数不能访问私有变量?【英文标题】:Why can't this friend function access the private variables?为什么这个友元函数不能访问私有变量? 【发布时间】:2013-06-18 15:06:02 【问题描述】:
class Student
public:
Student(int test)
:key(705)

    if(test == key)
    cout << "A student is being verified with a correct key: "<< test << endl;
    allow=1;
    
    else
    
        cout << "Wrong key" ;
    


friend void printResult();


private:
const int key;
int allow;


;

void printResult()

 if(allow==1)
 
   cout<< " Maths: 75 \n Science:80 \n English: 75" << endl;
  


int main()

int testkey;
cout << "Enter key for Bob: ";
cin >> testkey;

Student bob(testkey);

printResult();


函数 printResult 似乎无法从 Student 类访问私有变量 allow。我是在错误的地方对 printResult 进行原型制作还是语法错误? AFAIK,我们可以在课堂上的任何地方为朋友制作原型。

【问题讨论】:

你得到的确切错误是什么? 【参考方案1】:

printResult 不是成员函数,所以你需要给它一个Student 实例来操作。例如

void printResult(const Student& s)

 if(s.allow==1)
 
   cout<< " Maths: 75 \n Science:80 \n English: 75" << endl;
  

然后

Student student(1);
printResult(student);

【讨论】:

【参考方案2】:

这是因为allow 属于该类的一个实例,但没有引用任何实例。

您可能应该将printResult 设为类的成员函数,而不是将其设为外部函数让该函数引用Student 实例,以便您可以访问@987654324 @ 成员通过instance.allow ,其中instanceconst Student&amp; 类型的参数。

【讨论】:

【参考方案3】:

下面是一些有效的代码:

#include <iostream>
class Student

public:
Student(int test) : key(705)

    if(test == key)
    
        std::cout << "A student is being verified with a correct key: "<< test <<    std::endl;
        allow=1;
    
    else
    
        std::cout << "Wrong key" ;
    


friend void printResult(Student* student);

private:
    const int key;
    int allow;
;

void printResult(Student* student)

    if(student->allow==1)
    
        std::cout<< " Maths: 75 \n Science:80 \n English: 75" << std::endl;
    


int main(int argc, char* argv[])

    int testkey;
    std::cout << "Enter key for Bob: ";
    std::cin >> testkey;

    Student bob(testkey);

    printResult(&bob);

我对其进行了修改以将打印功能保留在全局空间中(仅基于您想要的外观)。它需要一个 Student* 参数,因为它被声明为朋友,所以它会看到“允许”变量。然而,这不是您想要滥用的 C++ 的一部分。小心你如何使用朋友。在更大的代码库中像这样使用它是危险的。全局功能通常不是要走的路。将 print 函数作为学生类中的公共成员函数可能是一种更好的做事方式。其他答案提供了显示该实现的代码。我决定向您展示此实现,因为它似乎更接近您在问题中寻找的内容。

我还确保在提及 cout 和 endl 时使用 'std::'。这消除了对“使用命名空间标准;”的需要在顶部。这只是在更复杂的项目中的良好编程实践。

【讨论】:

感谢您的额外提示!我需要时间来研究您所做的更改...非常有用的答案! 您可能要考虑的另一件事是以不同的方式进行输入。如果你给它意外的数据,一个裸露的 cin >> 可能会失败,从而丢掉你程序的其余部分。【参考方案4】:
class Student    
private:
const int key;
int allow;    
public:
Student(int test)
:key(705)

    if(test == key)
    cout << "A student is being verified with a correct key: "<< test << endl;
    int allow=1;
    
    else
    
        cout << "Wrong key" ;
    
    
friend void printResult(); 
void printResult() //<---  printResult() is a member function, so keep it inside the class

 if(allow==1)
 
   cout<< " Maths: 75 \n Science:80 \n English: 75" << endl;
  

; 

int main()

int testkey;
cout << "Enter key for Bob: ";
cin >> testkey;    
Student bob(testkey);   
bob.printResult(); // <--- you need to specify the owner of printResult()   

【讨论】:

【参考方案5】:

允许类友函数访问类实例的成员。 您应该将实例传递给函数,例如:

void printResult(Student s)

 if(s.allow==1)
 
   cout<< " Maths: 75 \n Science:80 \n English: 75" << endl;
  

【讨论】:

传递一个副本,这是不需要的。使函数采用 const Student&amp; 代替。 (除了参数列表,您无需更改任何内容)

以上是关于为啥这个友元函数不能访问私有变量?的主要内容,如果未能解决你的问题,请参考以下文章

c++知识点总结--友元&运算符重载

类与类之间的友元关系可以继承吗? 友元函数是类的成员函数吗?

友元函数都有哪些特点?

关于c++的友元函数

友元类使用例子

C++ 友元函数不起作用,在此上下文中为私有错误