Thread: Virtual Inheritance: Building Menu items

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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
    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

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    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

  11. #11
    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