Reputation: 138
I've got code below:
void CashFlow::execute (int cmd)
{
switch(cmd):
{
case BUY:
BuyProc ();
break;
case SELL:
SellProc ();
break;
......
}
}
What I'm thinking of doing is maybe create a map like std::map <int, void (CashFlow::*)()> CashflowProcs;
Then maybe use mCashFlowProcs = boost::assign::map_list_of (BUY, &CashFlow::BuyProc)(...etc)(..Etc.);
Then I can call it like (this->(mCashFlowProcs [cmd]))()
;
How do I turn this into template so it can be reused? Could there be issues with this implementation?
Note that I am not using C++11
Upvotes: 1
Views: 140
Reputation: 23803
Could there be issues with this implementation?
Yes, it is hard to maintain, as adding/removing Command would need a lot of maintenance, would be error prone, and difficult to test. So I suggest a design change before trying to just improve this particular code.
1 - If you can change your design:
Use a class
to represent a Command
class Command
{
public:
virtual void Execute() = 0;
virtual ~Command() {};;
};
class BuyCommand : public Command
{
public:
virtual void Execute() { cout << "BUY"; }
};
class SellCommand : public Command
{
public:
virtual void Execute() { cout << "SELL"; }
};
// ...
Command* bc = new BuyCommand();
// ...
bc->Execute();
2 - If (unfortunately) you cant change design that way
If the cmd
enumeration is known at compile time, and has a limited size, you can use an array of boost::function
, and you should definitely regroup your command in an enum
instead of using an int
.
enum { BUY = 0; SELL = 1; NB_CMDS= 2 };
...
boost::array<NB_CMDS, boost::function<void()>> // N is the number of commands.
indexing your array with, cmd, you simply call the function that has the index cmd
in this array.
If you don't know at compile time how many commands/functions you will need, you might need to replace the array by a std::vector
.
If one day you can use C++11, replace boost::
by std::
in the above snippets.
Upvotes: 1