Гетерогенный список и динамическое распределение массивов

У меня проблема с заполнением этого гетерогенного списка. Я передаю текстовый файл и использую его для заполнения данных об объектах, а затем добавляю их в список. Это мой первый раз, и я не могу понять, почему он не работает должным образом. Он должен сохранять каждый заполненный адрес объекта указателем в массиве указателей, правильно? Однако, когда я проверяю его, я вижу, что он сохраняется только в одном месте (* list) [0]. Наиболее релевантная часть, вероятно, будет взята из main.cpp. Спасибо!

main.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "student.h"
using namespace std;

int main()
{
string inputFileName;
string outputFileName;

cout << "Please enter the input file name: ";
getline(cin, inputFileName);

ifstream inputFile;
int NUMBEROFENTRIES;
inputFile.open(inputFileName.c_str());   //CLOSE
if(inputFile){
NUMBEROFENTRIES = int(inputFile.get())-int('0');

}else{
cout << "Failed to open file." << endl;
}

Student ** list; //create a pointer to Student pointer
list = new Student*[NUMBEROFENTRIES];  //dynamically allocated list of Student pointers

for(int i = 0; i < NUMBEROFENTRIES; i++)
{
string uselessNewLine;
getline(inputFile, uselessNewLine);

string tempfirstname;
string templastname;
getline(inputFile, templastname, ',');
inputFile.get();
getline(inputFile, tempfirstname);

char tempcourse = inputFile.get();
if(tempcourse == 'b'||tempcourse == 'B')
{
BioStudent bobj;

bobj.setNameAndCourse(tempfirstname, templastname, tempcourse);

string garbage;
getline(inputFile, garbage, ' ');

bobj.SetGrades(inputFile);

list[i] = &bobj; //I assume this is where the error is but i should be incrementing?

}

else if(tempcourse == 't' || tempcourse == 'T')
{
TheaterStudent tobj;

tobj.setNameAndCourse(tempfirstname, templastname, tempcourse);

string garbage;
getline(inputFile, garbage, ' ');

tobj.SetGrades(inputFile);

list[i] = &tobj;  //I assume this is where the error is but i should be incrementing?}

else if(tempcourse == 'c' || tempcourse == 'C')
{
CompsciStudent cobj;

cobj.setNameAndCourse(tempfirstname, templastname, tempcourse);

string garbage;
getline(inputFile, garbage, ' ');
getline(inputFile, garbage, ' ');

cobj.SetGrades(inputFile);

list[i] = &cobj;  //I assume this is where the error is but i should be incrementing?}else{
cout << "ERROR" << endl;
}

cout << (*list[0]).course << endl;

}delete [] list;
return 0;
}

student.h

#include <string>
#include <iostream>
using namespace std;class Student
{
public:
virtual double GetAverage()=0;  //Another pure virtual function
void setNameAndCourse(string fn, string ln, char tc);
Student();
char course;
char GetCourse();
protected:

string firstName;
string lastName;private:

};class BioStudent: public Student
{
public:
BioStudent();
void SetGrades(ifstream &input);
double GetAverage();

private:
int labGrade;
int test1;
int test2;
int test3;
int finalExam;

};class TheaterStudent: public Student
{
public:
TheaterStudent();
void SetGrades(ifstream &input);
double GetAverage();

private:
int participation;
int midterm;
int finalExam;

};class CompsciStudent: public Student
{
public:
CompsciStudent();
void SetGrades(ifstream &input);
double GetAverage();

private:
int assign1;
int assign2;
int assign3;
int assign4;
int assign5;
int assign6;
double assignAverage;
int test1;
int test2;
int finalExam;
};

student.cpp

#include "student.h"#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

using namespace std;

Student::Student()
{
firstName = "";
lastName = "";
course = ' ';
}

void Student::setNameAndCourse(string fn, string ln, char tc)
{
firstName = fn;
lastName = ln;
course = tc;

}

char Student::GetCourse()
{
return course;
}

BioStudent::BioStudent()
{
labGrade = 0;
test1 = 0;
test2 = 0;
test3 = 0;
finalExam = 0;
}

void BioStudent::SetGrades(ifstream& input)
{
input >> labGrade;
input >> test1;
input >> test2;
input >> test3;
input >> finalExam;

}

double BioStudent::GetAverage()
{
double toReturn = 0.0;
toReturn = ((labGrade*.3) + (test1*.15) + (test2*.15) + (test3*.15) + (finalExam*.25));
return toReturn;
}

TheaterStudent::TheaterStudent()
{
participation = 0;
midterm = 0;
finalExam = 0;
}

void TheaterStudent::SetGrades(ifstream &input)
{
input >> participation;
input >> midterm;
input >> finalExam;

}

double TheaterStudent::GetAverage()
{
double toReturn = 0.0;
toReturn = ((participation*.4)+(midterm*.25)+(finalExam*.35));
return toReturn;
}

CompsciStudent::CompsciStudent()
{
assign1 = 0;
assign2 = 0;
assign3 = 0;
assign4 = 0;
assign5 = 0;
assign6 = 0;
assignAverage = 0.0;
test1 = 0;
test2 = 0;
finalExam = 0;
}

void CompsciStudent::SetGrades(ifstream &input)
{
input >> assign1;
input >> assign2;
input >> assign3;
input >> assign4;
input >> assign5;
input >> assign6;
input >> test1;
input >> test2;
input >> finalExam;

}

double CompsciStudent::GetAverage()
{
double toReturn = 0.0;
assignAverage = ((assign1+assign2+assign3+assign4+assign5+assign6)/6);
toReturn = ((assignAverage*.3)+(test1*.2)+(test2*.2)+(finalExam*.3));
return toReturn;
}

-2

Решение

Вы правы, проблема здесь:

 list[i] = &bobj; //I assume this is where the error is but i should be incrementing?

и причина в том, что bobj определяется в стеке следующим образом:

 BioStudent bobj;

так что он будет уничтожен, как только закончится его окружающая область, и тогда ваш список будет содержать висячий указатель.

То, что вы хотите, это динамически размещаемый объект:

BioStudent* bobj = new BioStudent;

а потом :

list[i] = bobj;

Также не забывайте освобождать свои объекты или лучше использовать умные указатели.

0

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

Других решений пока нет …

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