Хорошо, еще один вопрос о C ++. Я изо всех сил, чтобы учиться, поэтому, пожалуйста, голые со мной. Пока вы, ребята, научили меня больше, чем мой профессор. Я ненавижу классы, которые основаны на Power Point, и любой вопрос, который вы задаете, на самом деле не отвечает. Так что для моего последнего проекта в этом году. Я пытаюсь сделать программу успеваемости на C ++. Используя классы и структуры, новые и удаляемые вместо 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 печатаются. Но только когда я = 2. курсы [i = 2] .name по-прежнему печатаются с правильными данными. Я могу добавить больше курсов и больше студентов, и они распечатываются очень хорошо, опять же, только когда i = 2 course_id получает данные мусора. Я застрял на несколько дней и пытался взглянуть на это по-другому, пока @wheaties не упомянул, что то, что я делал ранее, было правильным и должно быть публичным. Так кто-нибудь из вас может мне помочь?
Проблема:
в 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);
}
}
Твоя проблема:
Следующие:
courses[courses->count_courses].course_id;
Не делает то, что вы хотели бы. Это лечит courses
как массив Course
объекты, когда на самом деле это просто один (выделенный в куче) объект. Так что, как только count_courses
увеличивается, вы получаете доступ к памяти вне единого существующего Course
объект, который, как вы уже заметили, дает только мусор.
Как это исправить?
Правильный путь «C ++» будет использовать std::vector
s вместо указателей для Course
а также Student
списки. Но если ты действительно нужно идти с ручным распределением памяти, вы должны:
count_courses
а также count_students
из соответствующих классов и в CourseBook
, Каждый студент или объект курса представляет отдельный курс / студент, поэтому нет смысла хранить в нем счет.courses = new Course[count];
, Конечно, тогда вы должны переместить выделение из конструктора и сделать это в addCourse
вместо этого, где вы знаете, сколько предметов будет тамЕсли есть
Course * courses;
это означает, что у вас есть переменная, содержащая адрес в область памяти, содержащую Course
, Вы можете получить доступ к области памяти (после установки ее с помощью new
или же malloc
) написав
*courses = ...;
или же
courses->name.
Однако C (и C ++) позволяет применять индексирование к этому указателю:
courses[i]
что ничего кроме
*(courses + i)
то есть, следуя указателю, который вы получаете, увеличивая courses
с i
раз размер Course
,
Считают, что new Course
обеспечивает память для одного Course
а затем посмотрите на то, что ваш цикл в addCourses
делает …
Там нет необходимости для динамического выделения памяти, если вы используете std::vector
,
Существует только один объект класса курсов, который вы создаете в конструкторе 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++;
}
}