class 的向量在 for 循环后重置成员变量

Vector of a class resetting member variables after for loop

我有一个作业,我们需要使用向量的这种基本结构和 classes 来学习父子 classes 和多态性。这是我应该编写的函数的代码:

void assignStudents(vector<Student*>& v) {
    for (int i = 0; i < 5; i++)
    {
        cout << "Enter a study level: ";
        string input;
        cin >> input;
        if (input == "graduate")
        {
            Graduate inputClass;
            Student* inputParentClassPtr = &inputClass;
            v.push_back(inputParentClassPtr);
            v[i]->addToVector(input);
            inputParentClassPtr = nullptr;

        }
        else if (input == "undergraduate")
        {
            Undergraduate inputClass;
            Student* inputParentClassPtr = &inputClass;
            inputParentClassPtr->addToVector(input);
            v.push_back(inputParentClassPtr);
        }
        else
        {
            cout << "Please enter a valid response, either graduate or undergraduate" << endl;
            i--;
        }

    }
    for (size_t i = 0; i < v.size(); i++)
    {
        vector<string> studyLevels = v[i]->getStudyLevels();
        size_t size = studyLevels.size();
        for (int j = 0; j < size; j++)
        {
            cout << studyLevels[j];
        }
    }
}

我调试了程序,每次第一个 for 循环移动到下一个迭代时,我的 vector 中每个对象内的每个成员变量都变为空白,但是当我添加一个新的对象进入 vector,然后调用 addToVector() 函数返回。

我添加了底部 for 循环来检查是否有任何编辑发生,一旦我到达那个底部 for 循环,每个成员变量又是空的。

我在 Student class vector 中添加了 UndergraduateGraduate class。每个 Student class 内部都有一个受保护的 vector,称为 levels。我需要将 class 添加到包含我所有对象的 vector,然后编辑成员变量 vector 以包含表示 class 类型的字符串。

为什么每次完成 for 循环的迭代时,成员变量 (levels) 都会变为空白?

我只关注一部分,因为同一个问题在您的代码中出现了两次。

{
    Graduate inputClass; // create local student "on the stack"
    Student* inputParentClassPtr = &inputClass;
    v.push_back(inputParentClassPtr); // store address of student
    v[i]->addToVector(input);
    inputParentClassPtr = nullptr; // has no real effect
} // inputClass goes out of scope and is destroyed here

当块结束时,该块中的局部“堆栈”变量将被销毁。这意味着 Graduate 对象不再有效,并且您存储在 v 中的指针现在指向无法使用的内容。

要解决这个问题,您需要在动态内存中创建对象。

您应该将向量更改为存储 std::unique_ptr<Student>,并使用 std::make_unique() 创建对象,如下所示:

auto inputParentClassPtr = std::make_unique<Graduate>();
v.push_back(std::move(inputParentClassPtr));

但是,如果您不能这样做,您将需要使用 new 来代替,如下所示:

Student* inputParentClassPtr = new Graduate();
v.push_back(inputParentClassPtr);

无论哪种方式,即使 inputParentClassPtr 仍然在块的末尾被销毁,它只是一个指针,它指向的 Graduate 对象仍然存在。

如果使用 new,则在使用完向量后需要 delete 向量中的所有对象,否则会发生内存泄漏。使用 std::unique_ptr 将为您处理。