I have an assignment where we need to use this basic structure of vectors and classes to learn about parent and child classes and polymorphism. Here is the code of the function I'm supposed to write:
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];
}
}
}
I debug the program and every time the first for
loop moves on to the next iteration, every member variable inside each object in my vector
goes blank, but then when I add a new object into the vector
, then call the addToVector()
function they come back.
I added the bottom for
loop to check if any editing is happening, and once I get to that bottom for
loop, every member variable is empty again.
I have the Student
class vector
where I am adding Undergraduate
and Graduate
classes to. Every Student
class has a protected vector
inside called levels
. I need to add the class to vector
that holds all my objects, then edit the member variable vector
to include the string representing the type of class it is.
Why do the member variables (levels
) go blank every time it finishes an iteration of the for
loop?
CodePudding user response:
I'll just focus on one part, as the same issue appears twice in your code.
{
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
When the block ends, the local "stack" variables from that block are destroyed. That means the Graduate
object is no longer valid, and the pointer you stored in v
is now pointing at something unusable.
To fix that, you need to create the objects in dynamic memory.
You should change your vector to store std::unique_ptr<Student>
, and create the objects using std::make_unique()
, like this:
auto inputParentClassPtr = std::make_unique<Graduate>();
v.push_back(std::move(inputParentClassPtr));
But, if you can't do that, you will need to use new
instead, like this:
Student* inputParentClassPtr = new Graduate();
v.push_back(inputParentClassPtr);
Either way, even though inputParentClassPtr
is still destroyed at the end of the block, it is only a pointer and the Graduate
object it pointed to is still alive.
If you use new
, you'll then need to delete
all the objects in the vector when you are done using them, or you'll have a memory leak. Using std::unique_ptr
will handle that for you.