我需要在课程中添加多个学生,但它会覆盖最后一个条目。
我尝试设置对象的地址,也尝试使用方括号运算符,但这会导致内存泄漏。问题出在AddStudent
函数上
class Student {
public:
Student() { name = "unknown"; };
Student(string n) { name = n; };
void Print() { cout << name << endl; };
string GetName() { return name; };
private:
string name;
};
class Course {
public:
Course(int i) {
id=i;
nstudents=0;
capacity=0;
};
void AddStudent(Student s) {
students=&s;
nstudents++;
};
private:
int capacity;
int nstudents;
Student* students;
int id;
};
只允许我增加一名学生。
答案 0 :(得分:1)
“ students =&s;”您使用的是按值复制变量的地址,该变量在离开函数后会悬空。您不存储学生。您必须在其中放入类似std :: vector之类的容器,然后在其中复制/移动学生。
这里是带有复制和移动的std :: vector。
class Course {
public:
Course(int i) {
id=i;
};
void AddStudent(const Student& s) {
students.push_back(s);
};
void AddStudent(Student&& s) {
students.push_back(std::move(s));
};
private:
std::vector<Student> students;
int id;
};
答案 1 :(得分:0)
您需要为学生数组分配内存。在构造函数类中添加:students = new Student[SomeInitialSize]
。此外,在add方法中,您还需要检查students
的大小是否足以存储另一个{ {1}},如果没有,则需要分配更多的内存。
答案 2 :(得分:0)
添加第一个学生时,students
设置为指向s
函数内的AddStudent
。问题是因为s
是函数的局部变量,因此在函数返回时将其销毁。因此students
现在是一个悬空指针,指向无处,因为它指向的内存不再用于存储Student
对象。为了在AddStudent
函数返回后保留内存,您必须使用new
动态分配它,但是这样做还有其他问题。
比方说,您为新学生动态分配了内存。当我们增加第二个学生时,将分配更多的内存来存储该学生。新的记忆可能最终会处在完全不同的位置。您的AddStudent
函数将设置students
指针以指向新的Student
对象,但是现在我们已经忘记了现有学生的存储位置。
那么我们该如何解决呢?我们可以分配Student
对象的数组,为新学生留下多余的空间。这样,所有学生都存储在连续的内存中,students
将始终指向第一个对象。在我们的AddStudent
函数中,我们将通过执行students[nstudents] = s
之类的操作,将新学生放到当前的最后一个学生之后,再递增nstudents
。
这个问题是,如果我们超出了阵列的容量,我们将不得不分配一个更大的新阵列并复制所有内容,因为我们无法扩展现有的已分配内存块。或者,您可以使数组固定大小。但是有一个更好的解决方案:std::vector
。
std::vector
是一个标准的库容器,可以为您管理内存。您可以将学生存储在此处,并使用push_back
轻松添加一个。您可以通过询问老师,阅读good book或在线查找教程来学习如何使用向量(请注意,那里有很多不好的东西)。