Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi :),
I have experience in Java and now working with a project in c++.
The program consist of a few commands there every command is a class
(or actually an instance of one). My problem is to get a great design for further maintenance and expansion (e.g. say 20 new commands should be added and some removed, the easier the better this is done).

For a time ago I faced this problem in an other application written in Java. Were I created a new instance by the name of the class/command, it looked something like this:

<br />
Command c = (Command)Class.forName(str).newInstance();<br />
c.runCommand(str_args);<br />


Would it be possible to make something similar in c++ or must I choose
an other solution? :sigh:

If not, then how do you implement this effective in c++ so you
don't need an extremely long (if else) list or a solution that needs
a lot of changes and extensions every time a command is added?

(there will be a lot commands (>100))
(maybe I should mention it's not visual c++ .net but native c++ for win)

Thanks in advance, I would be very happy if you could come with some
great answers. //WaZoX
Posted

Short answer, no: C++ has no support for that.

I think you should have a look at prototype design pattern[^] (or, more generally to creational design patterns).
:)
 
Share this answer
 
v5
Comments
WaZoX 1-Sep-10 17:57pm    
Thanks for your answer, that can possibly work.
ThatsAlok 3-Sep-10 3:05am    
you need to correct your link, url is missing 'n' at end!
CPallini 3-Sep-10 3:17am    
Thank you, Alok. Why didn't you edit the link? :-)
Unless you're saving your commands for some other nefarious purpose (i.e. they've got an undo operation and once they're carried out they get stuck on an undo stack in case the user wants to back out) what you're really after is some way of executing an arbitrary chunk of code based on a string.

One way of doing this is to use a map, or other associative array:

C++
typedef std::map< std::string, command * > command_map;
command_map cmd_map;


where command is something like:

C++
class command
{
    public:
        virtual ~command() {}
        virtual void execute() = 0;
};


and then use that to look up and execute what command you want executed:

C++
void execute_command_by_name( const std::string &cmd_name,
                              const command_map *cmd_map )
{
    command_map::const_iterator iter( cmd_map.find() );
    if( iter != cmd_map.end() && iter->second )
    {
        iter->second->execute();
    }
}


If you really need some sort of creational pattern to generate commands then replace the pointer to the command in the map with a function or functor that creates commands and you'll get much the same effect. If you want to still go further you can even dynamically load the code for commands at runtime but how to do that is very OS specific.

Anwyay, I'm not sure that PROTOTYPE pattern is the one to use in this case - you don't really need an exemplar for your class to clone when you can use the original object. If you need to create commands, as I mentioned above, I'd personally use FACTORY METHOD rather than PROTOTYPE.

Cheers,

Ash

PS: Edit as I was actually talking about FACTORY METHOD not ABSTRACT FACTORY. Bum.
 
Share this answer
 
v2
Comments
WaZoX 2-Sep-10 16:00pm    
I figured out a similar version but this is what I really were after,
thank you very much!
ThatsAlok 3-Sep-10 3:03am    
I personally like factory method too..! frankly it's quite easy to implement
Aescleal 3-Sep-10 4:24am    
Actually on third thoughts the code I wrote was using abstract factory by the GoF definition. gack, confusing bloody classification. One day I'll understand the classification of factory patterns!
See also the example of DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE
in the <afx.h> if you have it :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900