【问题标题】:Friend function strange behaviour朋友功能奇怪的行为
【发布时间】:2014-09-18 06:30:27
【问题描述】:

我正在自学 C++,我制作的一个程序有点像学校信息系统,这不是我的第一个 OOP 程序,但这次我遇到了一个朋友函数的一些奇怪行为。 我有一个派生类Student,它有一个私有成员——Courses 对象的静态数组,最后是主容器类Class,它有一个成员——Students 对象的动态数组。

如您所见,student 的成员 student 是使用 Courses 类的友元函数计算得出的(calc_avg 接收到 Courses 的数组,将其成绩相加并除以课程编号),它的工作原理类似于一种魅力。 一旦我尝试计算Class 对象的平均成绩(class_avg),问题就开始了 - 我使用相同的逻辑 - 创建一个 Student 的朋友函数(class_avarage 可以访问每个学生的平均值)它将接收Student 对象的数组及其大小,将每个学生的平均成绩相加并除以数组大小 - 由于某种原因它接收并返回垃圾值,我已经尝试修复它 3 个小时,但我找不到问题,如果可以,请帮助我-这是相关代码(不包括独立派生类,并且最小化了输出函数):

main //只有容器对象创建和IO功能(包括所有.h文件)

Class test1;
test1.input_class();
test1.output_class();

Student.h

#include "Person.h"
#include "Courses.h"
#ifndef STUDENT_H
#define STUDENT_H

class Student : public Person
{
public:
    Student();
    void input_student ();
    void output_student ();
    friend float class_avarage (Student* array, int);
    ~Student();
protected:
private:
    Courses my_courses [6];
    float avg;
};

#endif // STUDENT_H

Student.cpp

#include "Student.h"

Student::Student()
{
//ctor
}
void Student::input_student ()
{
cout << "Please enter students info:" << endl;
input_info();
my_courses[0].input_grades ("Math");
my_courses[1].input_grades ("English");
my_courses[2].input_grades ("Science");
my_courses[3].input_grades ("History");
my_courses[4].input_grades ("Art");
my_courses[5].input_grades ("Sports");
}

void Student::output_student ()
{
int i;
cout << "Students info:" << endl;
output_info();
cout << "   Course  Grade" << endl;
for (i = 0; i < 6; i++)
{
    my_courses[i].output_grades ();
}
avg = calc_avg(my_courses, 6);
cout << "   " << "Average grade for student: " << avg << endl;
}
Student::~Student()
{
//dtor
}
float calc_avg (Courses* array, int size)
{
int i;
float sum = 0;
for (i = 0; i < size; i++)
{
    sum += array[i].grade;
}
return sum/size;
}

Courses.h

#include <iostream>
#include <iomanip>
#include <string>
#ifndef COURSES_H
#define COURSES_H

using std::cout;
using std::cin;
using std::endl;
using std::string;

class Courses
{
public:
    Courses();
    void input_grades(string);
    void output_grades();
    friend float calc_avg (Courses*, int);
    ~Courses();
protected:
private:
    string course_name;
    int grade;
};

#endif // COURSES_H

Courses.cpp

#include "Courses.h"

Courses::Courses() : course_name ("Default"), grade (-1)
{
//ctor
}
void Courses::input_grades (string temp_name)
{
course_name = temp_name;
cout << "Enter " << temp_name << " grade: ";
cin >> grade;
cin.get();
}
void Courses::output_grades ()
{
cout << "   " << course_name << ":    " << grade << endl;
}
Courses::~Courses()
{
//dtor
}

Class.h

#include <iostream>
#include <string>
#include "Teacher.h"
#include "Student.h"
#ifndef CLASS_H
#define CLASS_H

using std::cout;
using std::cin;
using std::endl;
using std::string;

class Class
{
public:
    Class();
    void input_class ();
    void output_class ();
    ~Class();
protected:
private:
    string class_name;
    Teacher class_teacher;
    Student* pupils;
    int students_number;
    float class_avg;
};

#endif // CLASS_H

Class.cpp

#include "Class.h"

Class::Class() : class_name ("A"), pupils (NULL), students_number (0), class_avg (0)
{
//ctor
}
void Class::input_class ()
{
int i;
//input class data
cin >> students_number;
cin.get();
pupils = new (std::nothrow) Student [students_number];
if (!pupils)
{
    cout << "Allocation failed!" << endl;
}
else
{
    for (i = 0; i < students_number; i++)
    {
        pupils[i].input_student();
    }
}
class_avg = class_avarage (pupils, students_number);
}
void Class::output_class ()
{
int i;
cout << "   Displaying info of class :" << class_name << endl <<
    "   Class average grade: " << class_avg << endl;
class_teacher.output_teacher();
cout << "   Number of students: " << students_number << endl << "   Students: " << endl;
for (i = 0; i < students_number; i++)
{
    pupils[i].output_student();
}

}
Class::~Class()
{
//dtor
}
float class_avarage (Student* array, int size)
{
cout << size << endl;
int i;
float total = 0;
for (i = 0; i < size; i++)
{
    total += array[i].avg;
}
return total/size;
}

【问题讨论】:

  • 代码太多,不管是什么错误,尽量缩小范围。
  • -1:你扔给我们的代码没有关注要解决的问题。
  • 如果分配失败,那么您的代码会继续调用 class_avarage(NULL, students_number) 导致未定义的行为。将new (std::nothrow) 更改为new,让异常冒泡到您要处理的位置。
  • 据我所知,您实际上并没有创建任何Class 的实例。所以实际上你没有展示足够的代码,你需要展示创建和使用Class对象的代码。由于您的 Class 具有破坏复制语义,我猜您正在复制 Class 导致麻烦。
  • 去掉pupilsstudents_number,改用std::vector&lt;Student&gt;,一举解决很多问题

标签: c++ oop friend


【解决方案1】:

为什么有人要使用朋友功能?只需为 Cource.grade 成员添加简单的 getter,为 Student.avg 添加简单的 getter。这将消除获取垃圾而不是数据的可能性。 另外,使用 std::vector 并将它们传递给 std::vector&,而不是数组和指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-24
    • 2012-06-23
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多