对于我今年的上一个项目,我正在尝试用C ++编写成绩簿程序。使用类与结构,new和delete而不是malloc和free,我将重新创建我以前用C编写的作业。在我的上一个问题中有人告诉我停止使我的变量私有,因为我有一个指向我的主类的类的指针。
在gradebook.h中
class Student {
public:
string last;
string first;
int student_id;
int count_student;
};
class Course {
public:
string name;
int course_id;
int count_course;
};
class Gradebook {
public:
Gradebook();
void addCourse();
void addStudent();
void printCourse();
void printStudent();
private:
Course *courses;
Student *students;
};
在gradebook.cpp
Gradebook::Gradebook() {
courses = new Course;
courses->count_course=0;
courses->course_id = 0;
students = new Student;
students->count_student=0;
students->student_id=0;
}
Gradebook::addCourse() {
int i, loop=0;
cout << "Enter number of Courses: ";
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Course ID: ";
cin >> courses[courses->count_courses].course_id;
cout << "Enter Course Name: ";
cin >> courses[courses->count_courses].name;
courses->count_course++;
}
}
Gradebook::addStudent() {
//same information from addCourse but goes to students variables
}
Gradebook::printCourse() {
int i;
for(i=0; i<courses->count_course; i++) {
cout << courses[i].course_id << "\t\t";
cout << courses[i].name << endl;
}
}
Gradebook::printStudent() {
int i;
for(i=0; i<students->count_student; i++) {
cout << students[i].student_id << "\t\t";
cout << students[i].last << "\t\t";
cout << students[i].first << endl;
}
}
当我运行addCourse函数然后运行printCourse它可以工作。
然后我运行addStudent函数然后运行printStudent它可以工作。
问题:
在我添加学生并重新运行printCourse后,我会在课程[i] .course_id打印时获得垃圾数据。但只有当i = 2时。课程[i = 2] .name仍然使用正确的数据打印。我可以添加更多课程并添加更多学生,他们打印出来就好了,只有当i = 2时,course_id才能获得垃圾数据。我已经被困了几天而且我试着以不同的方式看待它,直到@wheaties提到我以前做的事情是正确的并且它应该是公开的。你们其中一个人能帮助我吗?
答案 0 :(得分:1)
您的问题:
以下内容:
courses[courses->count_courses].course_id;
不做你想做的事。它将courses
视为一组Course
对象,而实际上它只是一个(堆分配的)对象。因此,只要count_courses
增加,就可以访问单个现有Course
对象之外的内存,正如您已经观察到的那样,它只产生垃圾。
如何修复?
正确的“C ++”方式是使用std::vector
而不是Course
和Student
列表的指针。但是,如果真的必须使用手动内存分配,则必须:
count_courses
和count_students
移出相应的类并进入CourseBook
。每个学生或课程对象代表一个单独的课程/学生,因此将计数存储在其中是没有意义的。courses = new Course[count];
。当然,你必须将配置移出构造函数,然后在addCourse
中进行,而你知道那里有多少项答案 1 :(得分:1)
问题:
在Gradebook::Gradebook()
中,您构建了一个Course
:
courses = new Course;
courses->count_course=0;
courses->course_id = 0;
Student
同样如此。您需要构造一个数组或使用一个STL的容器。对于这种情况,我建议使用std::list
或std::deque
。一个简单的用法是:
class Gradebook {
std::list<Course> courses;
}
void Gradebook::addCouse() {
int count = 0;
cout << "Courses count: ";
cin >> count;
while (count-- > 0) {
Course course;
cout << "Course ID: ";
cin >> course.id;
cout << "Course name: ";
cin >> course.name;
courses.push_back(course);
}
}
void Gradebook::printCourse() {
cout << "There are " << courses.size() << " courses" << endl;
for (std::list<Course>::iterator i = courses.begin(); i != courses.end(); ++i) {
cout << " ID: " << i->id << " name: " << i->name << endl;
}
}
如果您希望使用std::vector
,则只会更改addCourse
:
void Gradebook::addCouse() {
int count = 0;
cout << "Courses count: ";
cin >> count;
courses.reserve(count);
while (count-- > 0) {
Course course;
cout << "Course ID: ";
cin >> course.id;
cout << "Course name: ";
cin >> course.name;
courses.push_back(course);
}
}
答案 2 :(得分:0)
如果有
Course * courses;
这意味着您有一个包含地址的变量到包含Course
的内存区域。您可以通过编写
new
或malloc
建立之后)
*courses = ...;
或
courses->name.
但是,C(和C ++)允许您对此指针应用索引:
courses[i]
这只是
*(courses + i)
,即按照你所获得的指针,通过courses
增加i
Course
的大小来获得指针。
考虑new Course
为单个Course
提供内存,然后查看addCourses
中的循环内容...
如果您使用std::vector
,则无需动态内存分配。
答案 3 :(得分:0)
课程类中只有一个对象,您在Gradebook :: Gradebook()的构造函数中创建
您应该尝试创建任意数量的课程对象。你可以通过
来做到这一点 Gradebook::addCourse() {
int i, loop=0;
cout << "Enter number of Courses: ";
cin >> loop;
//add these lines here and remove them form Gradebook constructor
courses = new Course[loop];
courses->count_course=0;
courses->course_id = 0;
//^^^^^
for(i=0; i<loop; i++) {
cout << "Enter Course ID: ";
cin >> courses[courses->count_courses].course_id;
cout << "Enter Course Name: ";
cin >> courses[courses->count_courses].name;
courses->count_course++;
}
}