I am currently working on a school assignment which requires us to read and write two kind of derived objects into a file, but i cant seem to read them in correctly once i have saved them into a .dat file.
here's what i have got so far:
the base class, Human
#ifndef HUMAN_H
#define HUMAN_H
#include <iostream>
#include <string>
using namespace std;
class Human {
protected:
string name, id;
public:
Human(string n = "", string id = "") {
name = n;
this->id = id;
}
string getName() { return name; }
string getId() { return id; }
void changeName(string n) { name = n; }
void changeId(string id) { this->id = id; }
void showData() {
cout << "Name: " << name << endl;
cout << "ID: " << id << endl;
}
};
#endif
the derived class Advisee
// Forward declaration of class Advisor to selve the circular dependency of classes
// A pointer is used instead of an instance
class Advisor;
#ifndef ADVISEE_H
#define ADVISEE_H
#include "Human.h"
#include <fstream>
class Advisee : public Human {
private:
Advisor *myAdvisor;
public:
Advisee(string n = "", string id = "") : Human(n, id) { myAdvisor = NULL; }
Advisee(string n, string id, Advisor * myAdv);
~Advisee() {}
void load(string);
void save(string);
void showAdvisor();
void setAdvisor(Advisor * myAdv);
void killAdvisor() { myAdvisor = NULL; }
};
void Advisee::load(string path) {
ifstream loader(path.c_str(), ios::binary);
loader.read(reinterpret_cast<char*>(this), sizeof(*this));
loader.close();
}
void Advisee::save(string path) {
ofstream writer(path.c_str(), ios::binary);
writer.write(reinterpret_cast<char*>(this), sizeof(*this));
writer.close();
}
#endif
the other derived class Advisor
#ifndef ADVISOR_H
#define ADVISOR_H
#include "Advisee.h"
#include "Human.h"
class Advisor : public Human {
private:
static const int maxAdvisees = 10;
int numAdvisees;
Advisee * myAdvisees[maxAdvisees];
public:
Advisor(string n = "", string id = "") : Human(n, id) { numAdvisees = 0; }
~Advisor() {
/*for (int i = 0; i < numAdvisees; i++) {
delete myAdvisees[i];
}*/
}
int totalAdvisees() { return numAdvisees; }
void load(string path) {
ifstream loader(path.c_str(), ios::binary);
loader.read(reinterpret_cast<char*>(this), sizeof(*this));
loader.close();
}
void save(string path) {
ofstream writer(path.c_str(), ios::binary);
writer.write(reinterpret_cast<char*>(this), sizeof(*this));
writer.close();
}
void addAdvisee(Advisee *newAdv) {
if (!this->adviseeAdded(newAdv)) {
myAdvisees[numAdvisees] = new Advisee();
myAdvisees[numAdvisees] = newAdv;
myAdvisees[numAdvisees]->setAdvisor(this);
numAdvisees++;
}
}
void showAdvisees() {
if (numAdvisees) {
cout << "Advisees of " << name << endl;
cout << "--------------------------------------" << endl;
for (int i = 0; i < numAdvisees; i++) {
cout << myAdvisees[i]->getId() << " " << myAdvisees[i]->getName() << endl;
}
cout << endl;
} else {
cout << "No advisees set yet." << endl;
}
}
void killMe() {
for (int i = 0; i < numAdvisees; i++) {
myAdvisees[i]->killAdvisor();
}
for (int i = 0; i < numAdvisees; i++) {
delete myAdvisees[i];
}
}
void removeAdvisee(Advisee *adv) {
bool found = false;
for (int i = 0, x = 0; i < numAdvisees; i++) {
if (myAdvisees[i] == adv) {
delete myAdvisees[i];
found = true;
x++;
}
myAdvisees[i] = myAdvisees[i+x];
}
if (found) {
cout << "Advisee deleted." << endl;
adv->killAdvisor();
numAdvisees--;
} else {
cout << "Advisee not found." << endl;
}
}
// Function to test if the advisee passed is already in my advisee list
bool adviseeAdded(Advisee * adv) {
bool found = false;
for (int i = 0; i < numAdvisees; i++) {
if (myAdvisees[i] == adv) {
found = true;
}
}
return found;
}
};
#endif
Advisee::Advisee(string n, string id, Advisor * myAdv) {
name = n;
this->id = id;
if (myAdv) {
myAdvisor = myAdv;
if (!myAdvisor->adviseeAdded(this)) {
myAdvisor->addAdvisee(this);
}
}
}
void Advisee::setAdvisor(Advisor * myAdv) {
if (myAdv) {
myAdvisor = myAdv;
if (myAdvisor->adviseeAdded(this)) {
myAdvisor->addAdvisee(this);
}
}
}
void Advisee::showAdvisor() {
if (myAdvisor) {
cout << "Advisor of " << this->name << endl;
cout << "--------------------------------------" << endl;
myAdvisor->showData();
} else {
cout << "No advisor set yet." << endl;
}
}
each Advisor/Advisee has methods load() and save() respectively, which load or saves the object into a file as passed in by the parameter of the methods.
here's how i saved them into a file ( inside main() ):
string path1 = "write1.dat";
string path2 = "write2.dat";
Advisor david("David", "24234");
Advisor ken("Ken", "123213");
Advisee peter("Peter", "123023");
david.save(path1);
ken.save(path1);
peter.save(path2);
and here's how i load them:
Advisor advisors[5];
Advisee advisees[5];
advisors[0].load(path1);
advisors[1].load(path1);
advisees[0].load(path2);
advisees[0].setAdvisor(&advisors[0]);
advisors[0].showAdvisees();
cout << endl;
advisors[1].showAdvisees();
cout << endl;
advisees[0].showAdvisor();
when compiled, the program crashes and shows to the line "Advisor of"
can anyone teach me how to solve this? is the way im doing it correct or should there be another way? is it ok to write objects containing pointers to a file?
thanks in advance :D