OOP menus?
So after looking through the CPP Workshop Project 1 and seeing that a lot of people did their Menu system with objects, I was a bit confused. I don't quite understand the point of doing this, I wasn't able to see the benefits of doing OO over having a function for every menu and just calling those specific functions when needed.
So my question is in the general regard, not exclusive to the Project. How is making an OO menu system beneficial over functions that send you to another function?
It is an added abstraction.
Hardcoding what menu options exist and what functions they trigger makes it far more difficult to reuse the bits of the menu that don't care what the options are (which should be all of the menu).
Hardcoding what menu options exist and what functions they trigger makes it far more difficult to reuse the bits of the menu that don't care what the options are (which should be all of the menu).
Quote:Original post by Telastyn
It is an added abstraction.
Hardcoding what menu options exist and what functions they trigger makes it far more difficult to reuse the bits of the menu that don't care what the options are (which should be all of the menu).
But there would be several different menus that each have their own options, so I don't understand how to really utilize OOP. And shouldn't the menu's care about the options since each menu is different?
Quote:Original post by ShakedownQuote:Original post by Telastyn
It is an added abstraction.
Hardcoding what menu options exist and what functions they trigger makes it far more difficult to reuse the bits of the menu that don't care what the options are (which should be all of the menu).
But there would be several different menus that each have their own options, so I don't understand how to really utilize OOP. And shouldn't the menu's care about the options since each menu is different?
Just because the presented solution (in the workshop project) were not very advanced doesn't mean that you can't handle menu in a very abstracted way in C++.
Typically, the menu shouldn't care about the options. The menu should display the options, and perhaps provide a mean to retrieve the user choice. The application then use this menu object to create different menus, and handle these menus the way it wants.
A typical (althouhg bad, IMHO) is to inherit the menu class and to handle each option in the derived class. This is pretty limited. A Better option should try to make the menu class completelly indifferent to the menu it handles - so all processing occurs externally (after a message is sent, or when the application retrieves a specific code from the menu class).
To be honnest, I don't fully understand what you don't understand, so if you want to give us more information, I'll make sure that you'll get a clearer answer :)
So I don't understand how you can have menu objects each present different options. Like you have your Main Menu:
And then the user chooses, say 2. Store, so it goes to the store menu:
And the user chooses 1. Buy Goods, so it goes to the Buy Goods menu:
And then on and on.
So what I don't get is how can you have a class Menu and produce several instances of the class and have each one of them have different options? It seems like you would have to derive a class from the Menu class for each of the different menus. And doing that seems more complicated than making a bunch of different functions for each of the menus.
Where would you like to go?1. Home2. Store3. Office4. France
And then the user chooses, say 2. Store, so it goes to the store menu:
Welcome to the Store! What do you need?1. Buy Goods2. Sell Goods3. Talk to the Manager4. Go Back to the Main Menu
And the user chooses 1. Buy Goods, so it goes to the Buy Goods menu:
What do you want to buy?1. This2. That3. These4. Those
And then on and on.
So what I don't get is how can you have a class Menu and produce several instances of the class and have each one of them have different options? It seems like you would have to derive a class from the Menu class for each of the different menus. And doing that seems more complicated than making a bunch of different functions for each of the menus.
You would have to change the member variables during runtime. One way to do this might be to store the menu choices inside a data file and to load/parse that file when the object is created.
This is a good case for what is typically known as data driven design. Basically, instead of having your menu options be directly coded, you write a very general "menu" class and then feed it data to control what exactly it displays.
As a very, very rough example:
Of course, the particular case of menus is complicated somewhat by the fact that you need the menu to respond to user selections. Obviously, that's going to be different each time, and you need unique code for handling each menu item. There are plenty of ways to accomplish that, though.
As a very, very rough example:
class Menu{// Type definitionspublic: typedef std::string OptionType; typedef std::vector<OptionType> OptionListType;// Constructionpublic: Menu(const std::string& title) : Title(title) { }// Operationspublic: void AddOption(const OptionType& option) { Options.push_back(option); } void Display() { std::cout << Title << "\n"; unsigned item = 0; for(OptionListType::iterator iter = Options.begin(); iter != Options.end(); ++iter) { std::cout << (++item) << ". " << (*iter) << "\n"; } std::cout << std::endl; }// Internal dataprotected: std::string Title; OptionListType Options;};// Example usageint main(){ Menu mainmenu("Main Menu"); mainmenu.AddOption("Play Game"); mainmenu.AddOption("High Scores"); mainmenu.AddOption("Quit"); mainmenu.Display();}
Of course, the particular case of menus is complicated somewhat by the fact that you need the menu to respond to user selections. Obviously, that's going to be different each time, and you need unique code for handling each menu item. There are plenty of ways to accomplish that, though.
In what you are describing, I would make the Menu class store a list of Menu objects. Each Menu has a name. Then, to display the menu, you write out the number and the name of the submenu. When the user makes a choice, you hand over control to that numbered submenu. This way, only the place that constructs all the menus has to know about what the choices are.
The key tidbit you might be missing is the fact that there are variables for functions. The concept is fairly simple: a variable exists which can be invoked and when invoked calls variable functions.
The menu's job then is to format a list of pairs. A representation, and an action (one of these variables) to trigger if selected (the selection is perhaps part of the menu, perhaps done by something separate).
The Workshop likely didn't cover these. "Function pointers" are the underlying C++ way to handle variable methods, but using a "function object" (like boost::function) is a lot nicer. This is one area where C++ is wanting in comparison to other languages.
The menu's job then is to format a list of pairs. A representation, and an action (one of these variables) to trigger if selected (the selection is perhaps part of the menu, perhaps done by something separate).
The Workshop likely didn't cover these. "Function pointers" are the underlying C++ way to handle variable methods, but using a "function object" (like boost::function) is a lot nicer. This is one area where C++ is wanting in comparison to other languages.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement