1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int END = -1, NO_SUBMENU = 0, GO_BACK = 0;
class Menu {
public:
Menu() {id = lastId++;}
~Menu();
void Insert (const char *foodName, const double cost, Menu* submenu = nullptr, const int pos = END);
void Delete (const int pos = END);
int Print() const;
int Choose() const;
int ID() {return id;}
private:
class Option {
public:
Option (const char*, const double, const Menu* = nullptr);
~Option();
const char* Name() {return name;}
double Price() {return price;}
const Menu* Submenu() {return submenu;}
Option*& Next() {return next;}
void Print() const;
int Choose() const;
private:
char *name;
double price;
const Menu *submenu;
Option *next;
};
Option* first = nullptr;
Menu* parent = nullptr; // *** Added
std::vector<Menu*> submenus; // *** Added (not actually needed in this simple model, but might be useful later)
int id;
static int lastId;
friend class Option;
private:
void addToSubmenus (Menu* submenu) {submenus.emplace_back(submenu);} // *** Added
void setParent (Menu* parentMenu) {parent = parentMenu;} // *** Added
};
Menu::Option::Option (const char* foodName, const double cost, const Menu* menu): submenu (menu) {
name = new char [strlen (foodName) + 1];
strcpy (name, foodName);
price = cost;
next = nullptr;
}
Menu::Option::~Option() {
delete name;
}
void Menu::Option::Print() const {
cout << name;
if (!submenu)
cout << "....." << price;
else
cout << " -> (submenu)";
cout << endl;
}
int Menu::Option::Choose() const {
if (!submenu)
return NO_SUBMENU;
else {
cout << endl << "Submenu entered." << endl;
return submenu->Choose();
}
}
int Menu::lastId = 0;
Menu::~Menu() {
Menu::Option *current, *next;
for (current = first; current != nullptr; current = next) {
next = current->Next();
delete current;
}
}
void Menu::Insert (const char *str, const double cost, Menu* submenu, const int pos) {
Menu::Option *newOption = new Menu::Option (str, cost, submenu);
Menu::Option *current, *prev = nullptr;
int idx = 0;
if (submenu) { // ******************************** Added
addToSubmenus(submenu);
submenu->setParent(this);
}
for (current = first; current != nullptr && idx++ != pos; current = current->Next())
prev = current;
if (!prev) {
newOption->Next() = first;
first = newOption;
}
else {
newOption->Next() = current;
prev->Next() = newOption;
}
}
void Menu::Delete (const int pos) {
Menu::Option *current, *prev = nullptr;
int idx = 0;
for (current = first; current != nullptr && current->Next() != nullptr && idx++ != pos; current = current->Next())
prev = current;
if (current) {
if (!prev)
first = current->Next();
else
prev->Next() = current->Next();
delete current;
}
}
int Menu::Print() const {
int n = 0;
Menu::Option *current = first;
for (current = first; current != nullptr; current = current->Next()) {
cout << ++n << ". ";
current->Print();
}
return n;
}
int Menu::Choose() const {
int n, choice;
Menu::Option *current = first;
do {
cout << "Please choose an option:" << endl;
n = this->Print();
cout << "Option? ";
cin >> choice;
} while ( (choice < 1 || choice > n) && (choice != GO_BACK) );
if (choice == GO_BACK) { // ***************************** The desired implementation
std::cout << "\nGoing back up one menu..." << std::endl << std::endl;
if (!parent) throw ("Error! No parent.");
return parent->Choose();
}
n = 1;
for (current = first; n != choice && current != nullptr; current = current->Next())
++n;
n = current->Choose();
return (n == NO_SUBMENU ? choice : n);
}
int main() { // Client code needs no change. :)
Menu menu;
menu.Insert ("Hamburger", 3.49);
menu.Insert ("Fries", 1.89);
menu.Insert ("Taco", 0.99);
menu.Insert ("Coke", 1.49, nullptr, 1);
Menu wineMenu;
wineMenu.Insert ("Red wine", 29.99);
wineMenu.Insert ("White wine", 39.99);
menu.Insert ("Wine", 0, &wineMenu);
Menu vintageWineMenu;
vintageWineMenu.Insert ("Chateau Talbot", 450.00);
vintageWineMenu.Insert ("Domaine de la Romanee", 1500.00);
vintageWineMenu.Insert ("Penfolds Grange Bin 95", 2700.00);
wineMenu.Insert ("Vintage Wine", 0, &vintageWineMenu, 0);
int menuChoice = menu.Choose();
cout << endl << "You chose option " << menuChoice << "." << endl;
}
|