C++使用类的成员函数作为友元函数

题目是:定义Student类和Score类,输出一个学生的成绩单(包括学号、姓名、高数、英语、政治、C++成绩)要求使用Student成员函数作为友元函数

我是这样写的(用的是VS2013):

Student.h

#pragma once
#include<string>
using namespace std;

class Student
{
public:
    Student(string num, string name)
    {
        this->num = num;
        this->name = name;
    }
    ~Student();
    void ShowData(Score &);
private:
    string num;
    string name;
};

Student.cpp

#include "stdafx.h"
#include "Student.h"
#include "Score.h"
#include <iostream>
using namespace std;

Student::~Student()
{
}

void Student::ShowData(Score &stu)
{
    cout << "=====学生信息=====\n";
    cout << "学号:\t" << num;
    cout << "\n姓名:\t" << name;
    cout << "\n高数:\t" << stu.Math;
    cout << "\n英语:\t" << stu.English;
    cout << "\n政治:\t" << stu.Politics;
    cout << "\nC++:\t" << stu.Cplusplus;
    cout << "\n===================\n";
}

Score.h

#pragma once
class Student;

class Score
{
public:
    Score(float Math, float English, float Politics, float  Cplusplus)
    {
        this->Math = Math;
        this->English = English;
        this->Politics = Politics;
        this->Cplusplus = Cplusplus;
    }
    ~Score();
    friend void Student::ShowData(Score &);
private:
    float Math;
    float English;
    float Politics;
    float Cplusplus;
};

Score.cpp

#include "stdafx.h"
#include "Score.h"

Score::~Score()
{
}

实验三.cpp

#include "stdafx.h"
#include "Score.h"
#include "Student.h"
#include <string>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    string num, name;
    float math, english, politics, cpluslus;
    cout<<"请输入学号,姓名以及数学,英语,政治和C++成绩:\n";
    cin >> num >> name >> math >> english >> politics >> cpluslus;
    Student stu(num,name);
    Score stu1(math,english,politics,cpluslus);
    stu.ShowData(stu1);
    return 0;
}

但是在Student.cpp文件中的ShowData函数中引用Score的数据成员时显示错误
图片说明

然后调试的时候编译器就提示有下面的错误:

错误 1 error C2027: 使用了未定义类型“Student” c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\score.h 17 1 实验三

错误 2 error C2061: 语法错误: 标识符“Score” c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.h 16 1 实验三

错误 3 error C2245: 将不存在的成员函数“Student::ShowData”指定为友元(成员函数签名与所有重载都不匹配) c:\users\xxxx\documents\visual studio 2013\proje
cts\实验三\实验三\score.h 17 1 实验三

错误 4 error C2511: “void Student::ShowData(Score &)”:“Student”中没有找到重载的成员函数 c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 12 1 实验三

错误 5 error C2597: 对非静态成员“Student::num”的非法引用 c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 14 1 实验三

错误 6 error C2597: 对非静态成员“Student::name”的非法引用 c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 15 1 实验三

错误 7 error C2248: “Score::Math”: 无法访问 private 成员(在“Score”类中声明) c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 16 1 实验三

错误 8 error C2248: “Score::English”: 无法访问 private 成员(在“Score”类中声明) c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 17 1 实验三

错误 9 error C2248: “Score::Politics”: 无法访问 private 成员(在“Score”类中声明) c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 18 1 实验三

错误 10 error C2248: “Score::Cplusplus”: 无法访问 private 成员(在“Score”类中声明) c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\student.cpp 19 1 实验三

错误 11 error C2027: 使用了未定义类型“Student” c:\users\xxxx\documents\visual studio 2013\projects\实验三\实验三\score.h 17 1 实验三
12 IntelliSense: 不允许使用不完整的类型 c:\Users\xxxx\Documents\Visual Studio 2013\Projects\实验三\实验三\Score.h 17 14 实验三

请问哪里不对呢,那两个类该怎么声明和引用啊?

ifndef STUDENT.H #define STUDENT.H

end if加上这些

在student.h中加个类的前置声明
class Score;
class Student
{
……

score里面的数据是private的 直接对象.数据 不能访问吧 改成public试一下

楼上说的 对的,你的成员变量都是private的,不能直接通过对象.来访问,要么通过友元,要么声明成public,要么写成员函数(推荐)
比如访问Math可以写一个public的float GetMath()函数

友元函数不能是另一个类中的成员函数。要是公共函数才能调用类中的私有变量。

void ShowData(CScore &sc)
{
cout << sc.m_fCplusplus << "\t";
}

#pragma once
class CScore
{
float m_fMath;
float m_fEnglish;
float m_fPolitics;
float m_fCplusplus;
public:
CScore(float fMath, float fEnglish, float fPolitics, float fCplusplus);
friend void ShowData(CScore &sc);
~CScore();
};

友元函数最好不要常用,这个破坏了类的结构。

当只使用了类的指针时, 才能以class xxxx 这样做声明, 然后在类中使用.

一但访问了类成功, 或者函数, 那么必须有类的完整实现.
而你这种程序就有这样的错误.

实际上应该先在student的类定义前加上class Score,要不然里面的函数使用的score类型就是非法的完了之后主程序要满足先载入友元函数原型所在的类,在载入调用友元函数的类的头文件。实际上他应该是这样子,要先把友元函数原型所在的类放在调用类的前面,要先读取了函数里面的内容再来调用,如果先调用再载入函数原型的话,他理解为了你直接调用保护变量,自然就提示没法访问了。