#c #loops #class #vector #instance
#c #циклы #класс #вектор #экземпляр
Вопрос:
Я создал класс для ученика с курсом и оценкой, программа продолжает запрашивать нового ученика, пока не будет указано имя stop . Для хранения этих экземпляров я хочу использовать вектор, но я не нашел другого способа их хранения, кроме как сначала создать массив для экземпляров, а затем поместить их обратно в вектор. Возможно ли выделить место для одного экземпляра и удалить значения, сохраненные в Student student после использования, чтобы его можно было использовать повторно?
int i=0;
Student student[20];
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student[i].name);
while((student[i].name) != "stop")
{
student[i].addcoursegrade();
students.push_back(student[i]);
i ;
cout << "Name?" << endl;
getline(cin,student[i].name);
if((student[i].name) == "stop")
break;
};
Я также использую векторы внутри класса для хранения значений для курса и оценки, поскольку они также должны расти. Код для класса находится здесь:
class Student {
public:
string name;
void print() {
cout << name ;
for (int i = 0; i < course.size(); i )
cout << " - " << course[i] << " - " << grade[i];
cout<<endl;
}
void addcoursegrade() {
string coursee;
string gradee;
cout << "Course?" << endl;
getline(cin, coursee);
course.push_back(coursee);
while (coursee != "stop") {
cout << "Grade?" << endl;
getline(cin, gradee);
grade.push_back(gradee);
cout << "Course?" << endl;
getline(cin, coursee);
if (coursee != "stop")
course.push_back(coursee);
else if(coursee == "stop")
break;
}
};
private:
vector<string> course;
vector<string> grade;
};
Комментарии:
1. Просто используйте один
Student
экземпляр, а не массив. Для чистоты поместите его в цикл..push_back
копирует объект, поэтому вам не нужны отдельные экземпляры для начала.2. «но я не нашел другого способа их хранения, кроме» Как именно вы пытались «найти» способы сделать это? Например, вы пробовали использовать поисковую систему для поиска примеров использования .push_back ?
3. Обратите внимание, что использование массива здесь почти сводит на нет смысл использования a
vector
. Как толькоStudent
будет введен 21-й, Ка-бла-бла!4. Посмотрите это . Нет проблем с помещением a
Student
в вектор. Итак, возьмите этот код, добавьте к нему и продублируйте проблему, которую, как вы утверждаете, вы видите. Или просто примите код по ссылке как хороший и работайте оттуда.
Ответ №1:
Вместо того, чтобы создавать массив, а затем возвращать его обратно, просто сохраните один экземпляр и переназначьте его:
Student student;
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student.name);
while((student.name) != "stop")
{
student.addcoursegrade();
// this line copies the student in the vector
students.push_back(student);
// then, reassign the temp student to default values
student = {};
cout << "Name?" << endl;
getline(cin,student.name);
if((student.name) == "stop")
break;
};
Комментарии:
1. Ключевым моментом здесь и, возможно, причиной путаницы OP является то, что
vector
в нем хранятся типы значений, поэтому содержимоеstudent
копируетсяstudents.push_back(student)
, оставляяstudent
его доступным для повторного использования.2. student = {} было именно тем, что я искал. Большое спасибо!: D
3. С удовольствием! Кроме того, помните, что
= {}
это не созданиеstudent
другого ученика, а просто переназначение значений по умолчанию. И это нормально, поскольку, когда вы нажимаете назад, он создает копию в векторе.
Ответ №2:
Меня беспокоило несколько вещей:
- То, как были структурированы ваши циклы, дублируя
getline
. Я предпочитаю массив while(true) с разрывом при появлении завершающего ввода. - Нет необходимости в массиве в стиле C.
std::vector
это путь! - отдельные массивы для курса и оценки. Вместо этого я предпочитаю одну запись, в которой хранятся как курс, так и оценка
- индексы в ваших циклах, которые используются только для доступа к элементам в коллекции. (Просто используйте цикл for на основе диапазона)
- Не создавайте
Student
объект, пока вам не понадобится. Используйте локальные переменные для ввода строк.
Как и во всем, что есть в C , можно сделать гораздо больше, чтобы улучшить его: например, добавить конструкторы для ваших объектов, инициализировать с помощью современного синтаксиса, использовать семантику перемещения и т. Д. Но я просто вношу минимальные изменения.
Я бы решил это так:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct CourseGrade {
string course;
string grade;
};
class Student {
public:
string name;
void print() {
cout << name;
for (autoamp; courseGrade : courseGrades) {
cout << " - " << courseGrade.course << " - " << courseGrade.grade;
}
cout << endl;
}
void addcoursegrades() {
while (true) {
cout << "Course?" << endl;
string course;
getline(cin, course);
if (course == "stop") break;
cout << "Grade?" << endl;
string grade;
getline(cin, grade);
CourseGrade courseGrade;
courseGrade.course = course;
courseGrade.grade = grade;
courseGrades.push_back(courseGrade);
}
}
private:
vector<CourseGrade> courseGrades;
};
int main() {
vector<Student> students;
while (true) {
cout << "Name?" << endl;
std::string name;
getline(cin, name);
if (name == "stop") break;
Student student;
student.name = name;
student.addcoursegrades();
students.push_back(student);
};
for (autoamp; student : students) {
student.print();
}
}