0

So I've been messing around with C++ trying to improve my knowledge and came across a project idea that I like, here is a sort of rough description of what I am trying to achieve.

I have a polymorphic setting where I have a base class of type Menu the interface of which is:

class Menu
{
protected:
   std::vector<std::string> elements;
public:
   friend void printMenu(Menu &);
   virtual void Commands(int);
};

and derived classes of type AMenu, BMenu...etc, bodies of whom look something like this:

class MainMenu : public Menu
{
public:
    MainMenu();
    void Commands(int);
};
Menu::Menu()
{
    elements = {"el1","el2"...};
}

Commands takes an int and has a switch statement to execute functions for each Menu called by printMenu()

rough implementation of printMenu()

void printMenu(Menu &M)
{
   //code   
    int counter = 1;

    for (auto x : M.elements)
        std::cout << '(' << counter++ << ')' << ' ' << x << '\n';
   //get user input
   M.Commands(option);
}

now I'd like it that if the user inputs say -1 the previous menu would be displayed to them something like AMenu --> BMenu --> CMenu --> BMen -- > AMenu

I've basically hit a wall trying, here's what I've tried thus far:

-- I tried creating a global std::stack where every time a menu is printed to the screen an object of that type gets stored in the stack, and if the user inputs -1 the object is thus popped -- Instead of the std::stack being global I've put it in Base as static static std::stack<Menu> S;and every time an object of type Menu is printed I push it to S and when the user enters -1 I pop S and printMenu(S.top());

and a couple other desperate attempts all of which failed to give me the result I desire, instead what I got was when the user inputs -1 it sends them to the previous menu but then when they try to access another option from the menu, the app just shuts down!

I'd like to know if the way I went is even remotely viable and if it is not please point me to the correct way.

I've got a solid understanding of basic C++ and just came off my Intro to OOP course in uni, also got basic knowledge of STL containers and data structures.

yacc
  • 2,915
  • 4
  • 19
  • 33
HashAL78
  • 81
  • 1
  • 2
  • 8
  • 4
    [`std::map`](https://en.cppreference.com/w/cpp/container/map) and [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) can be really handy. Every menu item gets a function. You use `map` to link the user command codes to the functions. That lets `std::map> menu;` do stuff like `menu[command](function parameters here);` to run the menu functions. – user4581301 May 30 '19 at 18:57
  • Thinking on applying this to your case, but not thinking enough to make a formal answer, `std::map> menumap;` and then `menumap[command]->Commands(anInt);` – user4581301 May 30 '19 at 19:01
  • @user4581301 are there other ways I could try? I've had little experience with smart pointers and I am not sure if what you proposed I could fully implement. edit: any good reading material recommendations? :P – HashAL78 May 30 '19 at 20:07
  • Smart pointer's not strictly necessary here. It just makes the job a bit easier and more compact. You could Automatically allocate all of the `Menu` derived classes somewhere with wider scope than the `map` and store raw pointers in the `map` since you know you don't need to manage them. – user4581301 May 30 '19 at 21:10
  • Figuring out smart pointers is mostly about [figuring out which to use when](https://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one). Usage of a `unique_ptr` is pretty much the same as normal with the caveat that you can't copy the `unique_ptr` (because then it wouldn't be unique). You can only transfer [ownership](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers). `shared_ptr` and `weak_ptr` are much more complicated to get right, but I don't have a good link that hasn't already been linked by the first link. – user4581301 May 30 '19 at 21:19

0 Answers0