класс — c ++ классы и данные мусора

Хорошо, еще один вопрос о 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 не упомянул, что то, что я делал ранее, было правильным и должно быть публичным. Так кто-нибудь из вас может мне помочь?

0

Решение

Проблема:

в 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);
}
}
1

Другие решения

Твоя проблема:

Следующие:

courses[courses->count_courses].course_id;

Не делает то, что вы хотели бы. Это лечит courses как массив Course объекты, когда на самом деле это просто один (выделенный в куче) объект. Так что, как только count_courses увеличивается, вы получаете доступ к памяти вне единого существующего Course объект, который, как вы уже заметили, дает только мусор.

Как это исправить?

Правильный путь «C ++» будет использовать std::vectors вместо указателей для Course а также Student списки. Но если ты действительно нужно идти с ручным распределением памяти, вы должны:

  1. Переехать count_courses а также count_students из соответствующих классов и в CourseBook, Каждый студент или объект курса представляет отдельный курс / студент, поэтому нет смысла хранить в нем счет.
  2. Выделите память, используя «новый массив»: courses = new Course[count];, Конечно, тогда вы должны переместить выделение из конструктора и сделать это в addCourse вместо этого, где вы знаете, сколько предметов будет там
  3. Не забудьте освободить выделенную память ..
1

Если есть

Course * courses;

это означает, что у вас есть переменная, содержащая адрес в область памяти, содержащую Course, Вы можете получить доступ к области памяти (после установки ее с помощью new или же malloc) написав

*courses = ...;

или же

courses->name.

Однако C (и C ++) позволяет применять индексирование к этому указателю:

courses[i]

что ничего кроме

*(courses + i)

то есть, следуя указателю, который вы получаете, увеличивая courses с i раз размер Course,

Считают, что new Course обеспечивает память для одного Course а затем посмотрите на то, что ваш цикл в addCourses делает …

Там нет необходимости для динамического выделения памяти, если вы используете std::vector,

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++;

}

}
0
По вопросам рекламы [email protected]