C++重载友元函数无法访问私有成员

c++ overloaded friend function can't access private members

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

当前正在进行一个项目,我的教授要求我们超载流式提取和输入运算符。我已经复制了他给我们开始实施的标题。这是我的标题学生。H:

// @file student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
using namespace std;
class Student {
    /** add all the setter and getter methods **/
    /**
   * @param is the input stream
   * @param course the student object reference
   * @return the input stream
   */
    friend istream &operator >> (istream &is, Student &student);
    /**
   * @param os the output stream
   * @param course the student object reference
   * @return the output stream
   */
    friend ostream& Student::operator << (ostream& os, const Student& student);
public:
    Student();
    Student(string firstName, string lastName, int id, char grade);
    void setFirstName(string firstName);
    string getFirstName();

private:
    string firstName;
    string lastName;
    int id;
    char grade;
};
#endif /* STUDENT_H */

这是我正在使用the file student.cpp

的定义
#include "student.h"
#include <iostream>
using namespace std;

istream &operator >> (istream &is, Student &student) {
    is >> student.firstName;
}

clion一直告诉我,firstname是私人的,因此无法访问,我是否有明显缺少的东西?我已经检查并仔细检查了我的格式,并将其移动了很多,我遇到了很多麻烦。

是的,我已经看过一个类似的标题为问题,他在何处遇到了他所使用的名称空间,尝试过并看不到结果。任何帮助都非常感谢。

我无法解释错误消息,但是该功能必须返回一个值。

istream &operator >> (istream &is, Student &student) {
    return (is >> student.firstName);
}

修复了该问题以及缺少的构造函数等,以及main(),它应该可以很好地编译。

P.S。将课堂学生放在您的命名空间中,所有您的命名空间,从来没有在标题文件中写using namespace std;

第一个问题是全局范围中的标头文件中的 using namespace std;。这可能会导致麻烦,所以不要做。

我个人不喜欢这种模式,即流操作员是班级的朋友。所以我这样做:

class Student {
public:
    Student();
    Student(std::string firstName, std::string lastName, int id, char grade);
    void setFirstName(std::string firstName);
    string getFirstName();
    std::istream &scan(std::istream &input);
    std::ostream &print(std::ostream &output) const;
private:
    string firstName;
    string lastName;
    int id;
    char grade;
};
std::istream &operator>>(std::istream &input, Student &student) {
   return student.scan(input);
}
std::ostream &operator<<(std::ostream &output, const Student&student) {
   return student.print(output);
}

对于编译器,没有区别。此模式还为其他解决方案打开了门,例如静态多态性,常规多态性(在这种情况下,您不必为每个类别定义流operator(。