c ++重载的朋友功能无法访问私人会员

时间:2018-02-06 01:23:24

标签: c++ c++11

目前正在做一个项目,我的教授要求我们重载流提取和输入操作符。我复制了他给我们的标题以开始我的实现。这是我的标题student.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 */

以下是我使用文件student.cpp

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


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

CLion一直告诉我firstName是私有的,因此无法访问,是否有任何明显的遗漏?我已经检查并仔细检查了我的格式,并将&符号移动了很多,我很难说出它是什么。

是的,我已经看过类似标题的问题,他正在使用他正在使用的命名空间的问题,尝试过并且没有看到任何结果。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我无法解释错误消息,但函数必须返回一个值。

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

修复那个和缺少的构造函数等,以及main(),它应该编译得很好。

P.S。将类Student放在一个名称空间中,这个名称空间属于您自己的名称空间,永远不会在头文件中写入using namespace std;

答案 1 :(得分:0)

第一个问题是全局范围内的头文件中的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);
}

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