Thread: Virtual Inheritance: Building Menu items

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    Virtual Inheritance: Building Menu items

    Following is my first attempt in using inheritance in my growing project. I have an already built menu but using member function pointers. To expand my C++ knowledge, i opted to upgrade that to virtual inheritance instead... Please note that the following code can be puzzled and needs lot of correction as this is not my strong area as yet. As said, the aim is to build menu items. Whenever there's a new menu to add, i suppose a new class will be added ..


    Code ...

    Code:
    class Menu {
    private:
    	virtual void MenuFunc() = 0;
    	virtual void AddItem(const std::string& s, char c, Func f);
    };
    
    class ViewContractMenu : virtual public Menu {
    
    public :
    	void MenuFunc()  
    	{
    		Clrscr();
    
    		cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "\t\t\t\tº  CONTRACT DETAILS  º\n";
    		cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    		rental.ViewContract();
    				
    		Pause();
    	}
    };
    
    class AddContractMenu : virtual public Menu {
    
    public :
    	void MenuFunc() 
    	{
    		Clrscr();
    
    		cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "\t\t\t\tº  ADD NEW CONRACT   º\n";
    		cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    		rental.CreateNewContract();
    
    		Pause();
    	}
    };
    
    class DeleteContractMenu : virtual public Menu {
    
    public :
    	void MenuFunc()  
    	{
    		Clrscr();
    
    		cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "\t\t\t\tº   DELETE CONTRACT  º\n";
    		cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    		rental.DeleteContract();
    
    		Pause();
    	}
    };
    
    class EditContractMenu : virtual public Menu {
    
    public : 
    	void MenuFunc()  
    	{
    		Clrscr();
    
    		cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "\t\t\t\tº    EDIT CONTRACT   º\n";
    		cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    		rental.EditContract();
    
    		Pause();
    	}
    };
    
    class ContractMenu : public ViewContractMenu,
    					 public AddContractMenu,
    					 public DeleteContractMenu,
    					 public EditContractMenu
    {
    public:
    	typedef static void (*Func)();
    private:
    	struct Item  
    	{
    		std::string	descr;
    		char        choice;
    		Func		func;
    	};
    	
    	typedef std::vector<Item> ItemVector;
    	ItemVector mainMenu, fleetMenu;
    	
    public: 
    	void addItem(const std::string& s, char c) 
    	{
    		Item item;
    		item.descr = s;
    		item.choice = c;
    		item.func = MenuItem(); /* NB: This is where the big issue is *** */
    
    		if(!isFleetMenu()) {
    			mainMenu.push_back(item);
    		}
    		else
    			fleetMenu.push_back(item);
    	}
    };
    This is not a compile/-error free code as some of the code is not added ... My intention is to seek help on the idea i have and whether am on the right direction

    thanks...

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    So why are you using virtual inheritance?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Where is 'rental' coming from?

    This isn't your source. (Or I overlooked something major.)

    How are we to critique a design if we don't have it?

    If all of your menu classes conceptually perform the same series of operations you want to employee polymorphism at the operation level.

    That is, maybe have a single 'menu_level' class that takes a 'std::vector<std::string>' and a "function object" during which the 'menu_level' class will employee as a callback.

    Soma

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Comments in red:
    Code:
    class Menu {
    private:
    	virtual void MenuFunc() = 0;
    	virtual void AddItem(const std::string& s, char c, Func f);
    };
    
    class ViewContractMenu : virtual public Menu {
    Don't use virtual here -- No need. [Same for all other similar ones]
    public :
    	void MenuFunc()  
    	{
    		Clrscr();
    
    		cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "\t\t\t\tº  CONTRACT DETAILS  º\n";
    		cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    		rental.ViewContract();
    				
    		Pause();
    	}
    };
    
    <...snip...>
    class ContractMenu : public ViewContractMenu,
    					 public AddContractMenu,
    					 public DeleteContractMenu,
    					 public EditContractMenu
    Why are you inheriting here - I don't think that's the right thing
    {
    public:
    	typedef static void (*Func)();
    private:
    	struct Item  
    	{
    		std::string	descr;
    		char        choice;
    		Func		func;
    	};
    	
    	typedef std::vector<Item> ItemVector;
    	ItemVector mainMenu, fleetMenu;
    	
    public: 
    	void addItem(const std::string& s, char c) 
    	{
    		Item item;
    		item.descr = s;
    		item.choice = c;
    		item.func = MenuItem(); /* NB: This is where the big issue is *** */
    Which menuitem is this? There are four in your iheritance, and they are not the same. 
    		if(!isFleetMenu()) {
    This is probably not the right way to achieve this - perhaps having two instances of this object, each with its own list would be the right solution. [1]
    			mainMenu.push_back(item);
    		}
    		else
    			fleetMenu.push_back(item);
    	}
    };
    Are you basing this on the menu system that I posted a long time ago?

    If you have "menu objects", then you should probably not use a function pointer, but rather use them as functors - store a pointer to "Menu", rather than a function pointer. When the menu is selected, call the Menu->MenuFunc(). Since it's a virtual function, it will call the right thing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    Are you basing this on the menu system that I posted a long time ago?
    Yes Mats...

    If you have "menu objects", then you should probably not use a function pointer, but rather use them as functors - store a pointer to "Menu", rather than a function pointer. When the menu is selected, call the Menu->MenuFunc(). Since it's a virtual function, it will call the right thing.
    Mats
    Never did functors before but i also thought the reason for using objects is running away from pointers .. But then i couldn't figure out a way to call each function ... But i will make a research on functors and return to you, perhaps an example on how i should do this may help too ...

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    Code:
    class ContractMenu : public ViewContractMenu,
    					 public AddContractMenu,
    					 public DeleteContractMenu,
    					 public EditContractMenu
    Why are you inheriting here - I don't think that's the right thing
    Well, i was trying to use multiple inheritance to have the scope of all the MenuFunc functions, that when i call item.func, it calls the right one. Actually this is where my cnfusion is ..

    Code:
    {
    public:
    	typedef static void (*Func)();
    private:
    	struct Item  
    	{
    		std::string	descr;
    		char        choice;
    		Func		func;
    	};
    	
    	typedef std::vector<Item> ItemVector;
    	ItemVector mainMenu, fleetMenu;
    	
    public: 
    	void addItem(const std::string& s, char c) 
    	{
    		Item item;
    		item.descr = s;
    		item.choice = c;
    		item.func = MenuItem(); /* NB: This is where the big issue is *** */
    Which menuitem is this? There are four in your iheritance, and they are not the same. 
    I think i forgot to do something like
    Code:
    item.func = ViewContractMenu::MenuItem();
    Is that right? but then perhaps i must have a switch statement based on the user choice and call the appropriate based on the user selection ...

    Code:
    		if(!isFleetMenu()) {
    This is probably not the right way to achieve this - perhaps having two instances of this object, each with its own list would be the right solution. [1]
    			mainMenu.push_back(item);
    		}
    		else
    			fleetMenu.push_back(item);
    	}
    };
    Emhh ... /thinking ... you mean, no actually, i'm not sure what you implying...

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What I mean is something like this:

    Code:
    class MenuItem()
    {
        virtual void MenuFunction() = 0;
    };
    
    class SomeSortOfMenuItem: public MenuItem
    {
         void MenuFunction() {
              cout << "Some Sort Of Menu stuff..." << endl;
         }
    };
    
    class SomeOtherfMenuItem: public MenuItem
    {
         void MenuFunction() {
              cout << "Some Other Menu stuff..." << endl;
         }
    };
    
    class Menu
    {
        vector<menu *> menu;
    public:
        void addMenu(MenuItem *menu ...);
    };
    
    Menu oneMenu;
    Menu twoMenu;
    
    ...
       MenuItem *m1 = new SomeSortOfMenuItem;
       oneMenu.addMenu(m1, ...);
       ... 
       MenuItem *m2 = new SomeOtherMenuItem; 
       twoMenu.addMenu(m2, ...)
    This is not meant as a complete example, but to show the concept. There are some simplifications, and probably typos in there.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    What I mean is something like this:

    Code:
    class Menu
    {
        vector<menu *> menu;
    public:
        void addMenu(MenuItem *menu ...);
    };
    
    Menu oneMenu;
    Menu twoMenu;
    
    ...
       MenuItem *m1 = new SomeSortOfMenuItem;
       oneMenu.addMenu(m1, ...);
       ... 
       MenuItem *m2 = new SomeOtherMenuItem; 
       twoMenu.addMenu(m2, ...)
    Mats
    My response ..

    Code:
    #ifndef MENU_H
    #define MENU_H
    
    class Menu
    {
    	std::vector<Menu *> menu;
    public:
        void addMenu(MenuItem *menu, const std::string& s, char c);
    private: 
    };
    
    #endif
    
    . . . . 
    
    /* Inside some class ??? */
    
    ???::CreateMainMenu()
    {
       Menu oneMenu;
    
       MenuItem *m1 = new ViewContractMenu;
       oneMenu.addMenu(m1, "View Contract", '1');
    }
    I'm kinda lost as to which class to actually create the menu list, the names Menu & MenuItem are already used up (hence the question marks)...

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    original Menu Class ..

    Here's my original Menu class just to give you an idea ..

    Code:
    // Class menu
    #ifndef MENU_H
    #define MENU_H
    
    #include <string>
    #include <vector>
    
    class GroupManager;
    class Rental;
    
    class Menu 
    {
    private:
    	typedef void (Menu::*Func)();
    
    	struct Item  
    	{
    		std::string	descr;
    		char        choice;
    		Func		func;
    	};
    
    	typedef std::vector<Item> ItemVector;
    	ItemVector mainMenu, fleetMenu;
    
    public:
    	Menu(GroupManager&, Rental&);
    	~Menu();
    
    	void choose();
    
    	void CreateMainMenu();
    	void CreateFleetMenu();
    
    	void toFleetMenu(bool);
    
    	void Menu::printItem(const Item& item) const; 
    	void addItem(const std::string& s, char c, Func f);
    	std::string Menu::whiteSpace(const Item& item, int slenght, char space) const;
    
    	// Menu functions
    	void Exit();
    	void Quit();
    	void Pause();
    	void Clrscr();
    	void ManageFleet();
    	void StartScreen();
    	void AddGroupOption();
    	void ViewGroupOption();
    	void ViewFleetOption();
    	void ReadFleetOption();
    	void SaveGroupOption();
    	void EditGroupOption();
    	void TitleDescription();
    	void ViewContractOption();
    	void EditContractOption();
    	void AddNewContractOption();
    	void DeleteContractOption();
    	bool isFleetMenu() { return fleetmenu; }
    	bool done() { return finished; }
    
    private:
    	GroupManager& grpMngr;
    	Rental& rental;
    	typedef ItemVector::iterator itemIterator;
    	bool finished;
    	bool fleetmenu;
    };
    #endif
    .cpp

    Code:
    // Menu class : function definitions
    
    #include "Menu.h" 
    #include "GroupManager.h"
    #include "Rental.h"
    #include "basic_input.h"
    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    Menu::Menu(GroupManager& f, Rental& r) : 
    mainMenu(), fleetMenu(),
    grpMngr(f),
    rental(r),
    finished(0),
    fleetmenu(0)
    {}
    
    Menu::~Menu() {}
    
    // Create a fleet Menu Items
    void Menu::CreateFleetMenu()
    {
    	toFleetMenu(true);
    	addItem("Description of Program", '1', &Menu::TitleDescription);
    	addItem("Read fleet from file", '2', &Menu::ReadFleetOption);
    	addItem("View a group List", '3', &Menu::ViewGroupOption);
    	addItem("View all existing goups", '4', &Menu::ViewFleetOption);
    	addItem("Add new group", '5', &Menu::AddGroupOption);
    	addItem("Edit group details", '6', &Menu::EditGroupOption);
    	addItem("Save group changes", '7', &Menu::SaveGroupOption);
    	addItem("Exit", '8', &Menu::Exit);  
    }
    
    // Create a Menu Items
    void Menu::CreateMainMenu()
    {
    	toFleetMenu(false);
    	addItem("View contract details", '1', &Menu::ViewContractOption);
    	addItem("Add new contract", '2', &Menu::AddNewContractOption);
    	addItem("Edit customer contract", '3', &Menu::EditContractOption);
    	addItem("Delete existing contract", '4', &Menu::DeleteContractOption);
    	addItem("Manage Fleet", '5', &Menu::ManageFleet);
    	addItem("Quit Program", '6', &Menu::Quit);
    }
    
    // Add Menu Item to the list
    void Menu::addItem(const std::string& s, char c, Func f) 
    {
    	Item item;
    	item.descr = s;
    	item.choice = c;
    	item.func = f;
    
    	if(!isFleetMenu()) {
    		mainMenu.push_back(item);
    	}
    	else
    		fleetMenu.push_back(item);
    }
    
    // Display Menu item on screen
    void Menu::printItem(const Item& item) const 
    { 
    	const int max_descr_width = 28;
    	string menuStr = whiteSpace(item, (int)(max_descr_width - item.descr.length() ), ' ');
    
    	cout << "     \t\t\tº" << item.choice <<  ". "  <<  menuStr << "º\n";
    	cout << "     \t\t\tº                               º\n";
    }
    
    // Find and append the remaining white spaces after description
    string Menu::whiteSpace(const Item& item,int slenght, char space) const
    {
    	string resultStr = item.descr;
    
    	for ( int count=0; count < slenght; count++ ) {
    		resultStr+=space;
    	}
    
    	return resultStr;
    }
    
    // Allow user to make a Menu selection
    void Menu::choose() 
    {
    	ItemVector menuItem;
    
    	Clrscr();
    
    	if(!isFleetMenu())
    	{
    		cout << "\n     \t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "     \t\t\tº         SHB CAR RENTALS       º\n";
    		cout << "     \t\t\t\314ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\271\n";
    		
    		menuItem = mainMenu;
    	}
    	else
    	{
    		cout << "\n     \t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    		cout << "     \t\t\tº          FLEET DETAILS        º\n";
    		cout << "     \t\t\t\314ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\271\n";
    
    		menuItem = fleetMenu;
    	}
    
    	for (itemIterator iter=menuItem.begin(); iter != menuItem.end(); ++iter) {
    		printItem(*iter);
    	}
    	cout << "     \t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n\n";
    
    	char c;
    
    	// Go through Menu until correct choice 
    	do 
    	{	
    		cout << "\n\n\t\tPlease choose above: ";
    		c=getch();
    				
    		itemIterator iter=menuItem.begin();
    
    		// Find the matching Menu choice
    		for (; iter != menuItem.end(); ++iter) 
    		{
    			if (iter->choice == c) 
    			{
    				Func f = iter->func;
    				(this->*f)();
    				return;
    			}
    		}
    	} while(1);
    };
    
    // *******************************************************************
    // Define static MENU functions
    
    void Menu::StartScreen()
    {
    	Clrscr();
    
    	puts("\t\t");
    	puts("  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ   ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛ      ÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ");
    	puts("  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛÛ    ÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ");
    	puts("  ÛÛÛÛ      ÛÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛÛÛ   ÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ   ÛÛÛÛ         ÛÛÛÛÛÛÛ  ÛÛÛÛ      ÛÛÛÛÛÛ	     ");
    	puts("  ÛÛÛÛÛÛÛÛÛÛÛÛÛ    ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛÛÛÛÛ ÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛ     ÛÛÛÛ    ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛ ÛÛÛÛÛÛÛÛ      ÛÛÛÛÛÛ	     ");
    	puts("  ÛÛÛÛ     ÛÛÛÛÛ   ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛ  ÛÛÛÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛ      ÛÛÛÛÛ  ÛÛÛÛ         ÛÛÛÛ   ÛÛÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛ       ÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛ    ÛÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛ       ÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛ     ÛÛÛÛ      ÛÛÛÛÛÛ		 ");
    	puts("  ÛÛÛÛ       ÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛ      ÛÛÛ      ÛÛÛÛÛÛ      ");
    	
    	puts("  °°°°       °°°°  °°°°°°°°°°°  °°°°      °°°      °°°°°°      ");
    	puts("  °°°°       °°°°  °°°°°°°°°°°  °°°°     °°°°      °°°°°°      ");
    	puts("  °°°°       °°°°  °°°°°°°°°°°  °°°°    °°°°°      °°°°°°		 ");
    	puts("  °°°°      °°°°°  °°°°         °°°°   °°°°°°      °°°°°°       ");
    	puts("  °°°°     °°°°°   °°°°°°°°°°°  °°°°  °°°°°°°      °°°°°°       ");
    	puts("  °°°°     °°°°    °°°°°°°°°°°  °°°° °°°°°°°°      °°°°°°       ");
    	puts("  °°°°°°°°°°°°°°   °°°°°°°°°°°  °°°°°°°° °°°°      °°°°°°       ");
    	puts("  °°°°°°°°°°°°°°°  °°°°         °°°°°°°  °°°°      °°°°°°       ");
    	puts("  °°°°       °°°°  °°°°°°°°°°°  °°°°°°   °°°°      °°°°°°       ");
    	puts("  °°°°°°°°°°°°°°°  °°°°°°°°°°°  °°°°°    °°°° °°°°°°°°°°°°°°°°  ");
    	puts("  °°°°°°°°°°°°°°   °°°°°°°°°°°  °°°°     °°°° °°°°°°°°°°°°°°°°  ");
    	cout << "\n\n  Press any key to continue . . .";
    	_getch();
    	//cin.ignore();
    }
    
    void Menu::TitleDescription( )
    {
    	void ProgramLimits();
    
    	Clrscr();
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº SHB RENT-A-CAR  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	cout << "\n\n\t\tThis program manages a fleet in a rental shop."
    		"\n\t\t   The fleet data is read from group files. "
    		"\n\n\t     A user is required to view from existing fleet files, "
    		"\n\t\t  update existing group, or enter a new group." 
    		"\n\n    ** The user may also edit, delete and save to an existing group file **\n\n";
    
    	Pause();
    
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº PROGRAM LIMITATIONS º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	cout << "\n\nINPUTS:\n\n"; 
    	cout << "FileName: [groupname].txt\n"; 
    	cout << "Engine Capacity: (i.e.) 1.8L must be 1800\n"; 
    	cout << "Dates: day, month, year, minute, second\n"; 
    	cout << "Tank Capacity [unknown=0, empty=1, half=2, full=3]\n\n";
    	
    	Pause();
    }
    
    void Menu::Clrscr()
    {
    	system("cls");
    }
    
    void Menu::Pause()
    {
    	puts("\n\n");
    	system("Pause");
    }
    
    void Menu::Exit()
    {
    	toFleetMenu(false);		
    	return;
    }
    void Menu::Quit()
    {
    	finished = true;
    	Clrscr();			
    	return;
    }
    
    // Manage selection between Menus
    void Menu::ManageFleet()
    {
    	toFleetMenu(true);
    	choose();
    }
    
    // Execute the required Menu
    void Menu::toFleetMenu(bool mStatus)
    {
    	fleetmenu=mStatus;
    }
    
    // Display Customer Contract
    void Menu::ViewContractOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº  CONTRACT DETAILS  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	rental.ViewContract();
    			
    	getch();
    }
    
    // Create new contract
    void Menu::AddNewContractOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº  ADD NEW CONRACT   º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	rental.CreateNewContract();
    
    	getch();
    }
    
    // Delete existing contract
    void Menu::DeleteContractOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº   DELETE CONTRACT  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	rental.DeleteContract();
    
    	getch();
    }
    
    // Menu Function : Edit the contract details
    void Menu::EditContractOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº    EDIT CONTRACT   º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	rental.EditContract();
    
    	getch();
    }
    
    // Menu Function : To list available groups
    void Menu::ViewFleetOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº FLEET DETAILS º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	grpMngr.ViewAllGroups();
    
    	Pause();
    }
    
    // Menu Function : To list available cars in a group
    void Menu::ViewGroupOption( )
    {
    
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº GROUP DETAILS º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	grpMngr.ViewAGroup();
    
    	Pause();
    }
    
    // Menu Function : To update the goup details
    void Menu::EditGroupOption( )
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº   ADD/DELETE CAR   º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	grpMngr.EditGroup();
    
    	Pause();
    }
    
    // Menu Function : To read in fleet from file
    void Menu::ReadFleetOption( )
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº   READ FILES  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	grpMngr.ReadGroups();
    
    	Pause();
    }
    
    // Menu Function : To add new car to fleet list
    void Menu::AddGroupOption( )
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº    NEW GROUP  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	// Add new group to the databalse 
    	grpMngr.AddNewGroup();
    
    	Pause();
    }
    
    // Menu Function : To save changes made to a group
    void Menu::SaveGroupOption()
    {
    	Clrscr();
    
    	cout << "\t\t\t\tÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n";
    	cout << "\t\t\t\tº   UPDATE GROUP  º\n";
    	cout << "\t\t\t\tÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n";
    
    	grpMngr.SaveGroupToFile();
    
    	Pause();
    }

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by csonx_p View Post
    My response ..

    Code:
    #ifndef MENU_H
    #define MENU_H
    
    class Menu
    {
    	std::vector<Menu *> menu;
    public:
        void addMenu(MenuItem *menu, const std::string& s, char c);
    private: 
    };
    
    #endif
    
    . . . . 
    
    /* Inside some class ??? */
    
    ???::CreateMainMenu()
    {
       Menu oneMenu;
    
       MenuItem *m1 = new ViewContractMenu;
       oneMenu.addMenu(m1, "View Contract", '1');
    }
    I'm kinda lost as to which class to actually create the menu list, the names Menu & MenuItem are already used up (hence the question marks)...
    It probably goes inside an "application" class or some such - or even in a standalone function called from main. Note that oneMenu was intended [in my code] to be some sort of "global", e.g. a singleton or actual global variable.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    What I mean is something like this:

    Code:
    class MenuItem()
    {
        virtual void MenuFunction() = 0;
    };
    
    class SomeSortOfMenuItem: public MenuItem
    {
         void MenuFunction() {
              cout << "Some Sort Of Menu stuff..." << endl;
         }
    };
    
    class SomeOtherfMenuItem: public MenuItem
    {
         void MenuFunction() {
              cout << "Some Other Menu stuff..." << endl;
         }
    };
    
    class Menu
    {
        vector<menu *> menu;
    public:
        void addMenu(MenuItem *menu ...);
    };
    
    Menu oneMenu;
    Menu twoMenu;
    
    ...
       MenuItem *m1 = new SomeSortOfMenuItem;
       oneMenu.addMenu(m1, ...);
       ... 
       MenuItem *m2 = new SomeOtherMenuItem; 
       twoMenu.addMenu(m2, ...)
    This is not meant as a complete example, but to show the concept. There are some simplifications, and probably typos in there.

    --
    Mats
    BTW, is it a good practice to have all these classes in their own cpp files.. Or should i just put all this inheritance in one .h class? call it MenuSomething.h

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by csonx_p
    BTW, is it a good practice to have all these classes in their own cpp files.. Or should i just put all this inheritance in one .h class? call it MenuSomething.h
    That is a matter of how you want to organise your classes into files, but at least place the abstract base class into its own file. That way someone can implement and/or use the interface without being forced to bring in the concrete classes.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by laserlight View Post
    That is a matter of how you want to organise your classes into files, but at least place the abstract base class into its own file. That way someone can implement and/or use the interface without being forced to bring in the concrete classes.
    cool, thought so too ... For now will have the pure virtual into a single class, the est into single .h ...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  2. HELP!!!!emergency Problem~expert please help
    By unknowppl in forum C++ Programming
    Replies: 9
    Last Post: 08-21-2008, 06:41 PM
  3. HELP!!!!emergency ~expert please help
    By unknowppl in forum C Programming
    Replies: 1
    Last Post: 08-19-2008, 07:35 AM
  4. Menu Item Caption - /a for right aligned Accelerator?
    By JasonD in forum Windows Programming
    Replies: 6
    Last Post: 06-25-2003, 11:14 AM
  5. C++ XML Class
    By edwardtisdale in forum C++ Programming
    Replies: 0
    Last Post: 12-10-2001, 11:14 PM