I am trying to write a class that uses DOM to write a list of Registrations to file as XML. The list of registrations contains three types of registration Registration which is the standard base registration class GuestRegistration and StudentRegistration which both derive from Registration.
The GuestRegistration class has a unique member category and the student registration has unique member qualification.
When I iterate over the list of registration pointers I only have access to the base class Registration's member functions. Is there any way I can access the subclasses' data members to use the getter functions getCategory and getQualification? I've tried creating a GuestRegistration and StudentRegistration pointer whenever the class name matches either of the two, but get a pointer conversion error.
void RegistrationListWriter::write(RegistrationList r) {
QList<Registration*> regList = r.getRegistrationList();
for (int i = 0; i < regList.size(); ++i) {
QString cn = regList.at(i)->metaObject()->className();
Person tempPerson = regList.at(i)->getAttendee();
appendRegistrationAndType(cn);
appendAttendee(tempPerson);
//this is where my issue starts
if (cn == "GuestRegistration") {
GuestRegistration guestReg = regList.at(i);
appendAttendeeCatagory(guestReg.getCatagory());
}
if (cn == "StudentRegistration") {
StudentRegistration* stuReg = regList.at(i);
appendAttendeeQualification(stuReg->getQualification());
}
appendBookingDate(regList.at(i)->getBookingDate().toString());
appendRegistrationFee(regList.at(i)->calculateFee());
}
}
You can use dynamic_cast to check for specific sub-classes:
void RegistrationListWriter::write(RegistrationList r) {
QList<Registration*> regList = r.getRegistrationList();
for (int i = 0; i < regList.size(); ++i) {
Registration *reg = regList.at(i);
appendRegistrationAndType(reg->metaObject()->className());
appendAttendee(reg->getAttendee());
if (GuestRegistration *guestReg = dynamic_cast<GuestRegistration*>(reg)) {
appendAttendeeCatagory(guestReg->getCatagory());
}
else
if (StudentRegistration* stuReg = dynamic_cast<StudentRegistration*>(reg)) {
appendAttendeeQualification(stuReg->getQualification());
}
// and so on ...
appendBookingDate(reg->getBookingDate().toString());
appendRegistrationFee(reg->calculateFee());
}
}
However, I would suggest implementing a virtual method in the Registration class itself that your sub-classes can override to register additional items as needed, eg:
class Registration {
...
virtual void appendExtraAttendees(RegistrationListWriter *writer){}
...
};
class GuestRegistration : public Registration {
...
virtual void appendExtraAttendees(RegistrationListWriter *writer);
...
};
void GuestRegistration::appendExtraAttendees(RegistrationListWriter *writer){
writer->appendAttendeeCatagory(getCatagory());
}
class StudentRegistration : public Registration {
...
virtual void appendExtraAttendees(RegistrationListWriter *writer);
...
};
void StudentRegistration::appendExtraAttendees(RegistrationListWriter *writer){
writer->appendAttendeeQualification(getQualification());
}
void RegistrationListWriter::write(RegistrationList r) {
QList<Registration*> regList = r.getRegistrationList();
for (int i = 0; i < regList.size(); ++i) {
Registration *reg = regList.at(i);
appendRegistrationAndType(reg->metaObject()->className());
appendAttendee(reg->getAttendee());
reg->appendExtraAttendees(this);
appendBookingDate(reg->getBookingDate().toString());
appendRegistrationFee(reg->calculateFee());
}
}
Alternatively:
class Registration {
...
virtual void appendAttendees(RegistrationListWriter *writer);
...
};
void Registration::appendAttendees(RegistrationListWriter *writer){
writer->appendAttendee(getAttendee());
}
class GuestRegistration : public Registration {
...
virtual void appendAttendees(RegistrationListWriter *writer);
...
};
void GuestRegistration::appendAttendees(RegistrationListWriter *writer){
Registration::appendAttendees(writer);
writer->appendAttendeeCatagory(getCatagory());
}
class StudentRegistration : public Registration {
...
virtual void appendAttendees(RegistrationListWriter *writer);
...
};
void StudentRegistration::appendAttendees(RegistrationListWriter *writer){
Registration::appendAttendees(writer);
writer->appendAttendeeQualification(getQualification());
}
void RegistrationListWriter::write(RegistrationList r) {
QList<Registration*> regList = r.getRegistrationList();
for (int i = 0; i < regList.size(); ++i) {
Registration *reg = regList.at(i);
appendRegistrationAndType(reg->metaObject()->className());
reg->appendAttendees(this);
appendBookingDate(reg->getBookingDate().toString());
appendRegistrationFee(reg->calculateFee());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With