У меня проблема с заполнением этого гетерогенного списка. Я передаю текстовый файл и использую его для заполнения данных об объектах, а затем добавляю их в список. Это мой первый раз, и я не могу понять, почему он не работает должным образом. Он должен сохранять каждый заполненный адрес объекта указателем в массиве указателей, правильно? Однако, когда я проверяю его, я вижу, что он сохраняется только в одном месте (* 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;
}
Вы правы, проблема здесь:
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;
Также не забывайте освобождать свои объекты или лучше использовать умные указатели.
Других решений пока нет …