This question is somewhat of a follow-up question to a question I have previously asked, as I'm trying to understand and implement the concepts suggested. I have refactored everything into smaller classes, and the overall design of a Weapon has been completed (and somewhat implemented). However, I'm having trouble accessing some members, and I believe I will have no trouble completing this project, once this roadblock has been surpassed, as a lot of sub-classes use a similar system.
Onto my problem, I have a parent, partly-virtual class, defined as follows:
class ModeInformation {
public:
ModeInformation() { m_CreateModes(); m_CreateModeChoiceList(); } // These two functions are always called when an object belonging to the ModeInformation parent class is created, as they store elements in two lists, one in which the pointer-to-Modes themselves are stored, the other where Menu options are stored according to the number of modes
virtual ~ModeInformation() {}
// Modes of a Weapon (virtual as they might be overridden in child classes)
virtual Mode* pMode1() const { return NULL; }
virtual Mode* pMode2() const { return NULL; }
virtual Mode* pMode3() const { return NULL; }
virtual Mode* pMode4() const { return NULL; }
virtual Mode* pMode5() const { return NULL; }
// Lists mentioned earlier
virtual list<string>* ModeChoiceList() const { return new list<string>; }
virtual list<Mode*>* Modes() const { return new list<Mode*>; };
// m_CreateModes() stores pointers-to-Mode in Modes(), if these are not NULL
void m_CreateModes() {
if (!pMode1() == NULL) { Modes()->push_back(pMode1()); }
if (!pMode2() == NULL) { Modes()->push_back(pMode2()); }
if (!pMode3() == NULL) { Modes()->push_back(pMode3()); }
if (!pMode4() == NULL) { Modes()->push_back(pMode4()); }
if (!pMode5() == NULL) { Modes()->push_back(pMode5()); }
}
// m_CreateModeChoiceList() stores strings in ModeChoiceList(), composed using the sstring library. Also a source of problems, as I will point out later on.
void m_CreateModeChoiceList() {
int i = 1;
for (list<Mode*>::iterator it = Modes()->begin(); it != Modes()->end(); it++) {
stringstream ChoiceDeclaration;
ChoiceDeclaration << "\n" << i << ".- Mode " << i;
ModeChoiceList()->push_back(ChoiceDeclaration.str());
i++;
}
ModeChoiceList()->push_back("\n0.- Quit to previous menu.");
}
// m_PrintBasicInfo() is called from classes that possess an object pertaining to the ModeInformation class (or derived child-classes), serves as a decision tree to judge whether the Mode List should be printed (in the case the Weapon being printed possesses more than one Mode), otherwise it will print the very first Mode
void m_PrintBasicInfo() {
if (Modes()->size() > 1) {
m_PrintModeList();
m_ChooseModeFromList();
}
else {
pMode1()->m_PrintBasicInfo(1);
}
}
// m_PrintModeList() prints each of the elements stored in ModeChoiceList()
void m_PrintModeList() {
list<string>::iterator it = ModeChoiceList()->begin();
while (it != ModeChoiceList()->end()) {
cout << *it << endl;
it++;
}
}
// m_ChooseModeFromList() provides a dynamic method for a user to choose which Mode's information will be printed
virtual void m_ChooseModeFromList() {
int Input = 0;
cout << "Please input your choice." << endl;
cin >> Input;
cout << endl;
list<Mode*>::iterator it = Modes()->begin();
switch (Input) {
case 1: if (it != Modes()->end()) { (*it)->m_PrintBasicInfo(Input); it++; break; }
else { m_ChooseInvalidModeFromList(); break; }
case 2: if (it != Modes()->end()) { (*it)->m_PrintBasicInfo(Input); it++; break; }
else { m_ChooseInvalidModeFromList(); break; }
case 3: if (it != Modes()->end()) { (*it)->m_PrintBasicInfo(Input); it++; break; }
else { m_ChooseInvalidModeFromList(); break; }
case 4: if (it != Modes()->end()) { (*it)->m_PrintBasicInfo(Input); it++; break; }
else { m_ChooseInvalidModeFromList(); break; }
case 5: if (it != Modes()->end()) { (*it)->m_PrintBasicInfo(Input); it++; break; }
else { m_ChooseInvalidModeFromList(); break; }
case 0: cout << "Returning to previous menu..." << endl; break;
default: m_ChooseInvalidModeFromList(); break;
}
}
// m_ChooseInvalidModeFromList() prints an invalid option message, and returns to m_ChooseModeFromList()
void m_ChooseInvalidModeFromList() {
cout << "Invalid option. Please choose a valid mode." << endl;
m_ChooseModeFromList();
}
};
I also have an example child class, belonging to an Weapon, which I am using to test the code's viability and execution. It is as detailed below:
class RailGunModeInformation : public ModeInformation {
public:
Mode* pMode1() const { return new RailGunMode1(); }
Mode* pMode2() const { return new RailGunMode2(); }
list<string>* ModeChoiceList() const { return new list<string>; }
list<Mode*>* Modes() const { return new list<Mode*>; }
};
Right now, it compiles, but I keep getting an "Unhandled exception at 0x0FC3CAB6 (ucrtbased.dll) in Factory Method.exe: An invalid parameter was passed to a function that considers invalid parameters fatal." error. No matter how much I try to rework this while keeping its overall function, I can't seem to get it to work, getting a load of different errors. So I figured I'd ask the experts for some help, as I've spent hours banging my head against the wall trying to jump over this hurdle.