[C++] Whats the soultion? Function pointers, Function objects or somthing else.

Started by
9 comments, last by Sneftel 16 years, 1 month ago
I have a class, well call it app. I am looking for a method of adding new functionality to it over time because I don't know all the requirements at the moment. Basically the app class represents my application, it has some data members, some of which are non trivial. The user will enter commands which I pass to an app object, through a "docommand" function. The "docommand" should take a command name, either a string or some uniquely generated id and call the appropriates functionality. I want something that is easy to expand later, meaning pick an new name for the command and write a single new function. Now I could have once big switch/case statement or a bunch of if, else ifs but thats sloppy. Id like it to be more like it has a vector or list of function objects and and It searches through the list for one with the right name then evokes it. Then all I would have to do to add new functionality is write the new function or function object and put it in the container. Should I use function objects or or function pointers. And how do I get them to access the data of the app class? If they are function pointers I suppose I could make them member functions. Or if they are function objects I suppose making them a friend of the app class. This is where I becomes unsure how to proceed.
Advertisement
Using function-objects, and passing a reference to the application object in the constructor, you will be able to do what you've just described.

The command-pattern ( http://en.wikipedia.org/wiki/Command_pattern ) might also be a thing of interest to you.

The DoCommand-function can use a std::map of function-objects to find the right command in O(log n)-time.

Best of luck!
Tristan
Hi there,
I'd go with a std::map.

typedef int(YourClass::*FunctionPointer)(const std::string&);
std::map<std::string, FunctionPointer> functionMap;

to be specific.

Than you just do:

functionMap["echo"] = &echoFunction

functionMap.find("echo");

Of course we could debate about your program design... but that's another question. =)

Have a nice day.

EDIT:
Okay Tristan beat me. =)
I think Function Objects might be more flexible.
Command design pattern. Adapting this to C++ should be fairly easy.
Is the command pattern really applicable here? It seems that in my case the client, invoker and receiver will all be the same class. Can this work?
Personally, I'd just use an existing scripting language like Python, Lua or AngelScript and whatever binding system it uses and not worry about the implementation details of how it maps names to function calls.
This is setting off all sorts of alarm bells in my programming aesthetic smoke detector. Why, exactly, are you invoking functionality through strings rather than function names?
I don't know any of those scripting languages.

Quote:Original post by Sneftel
This is setting off all sorts of alarm bells in my programming aesthetic smoke detector. Why, exactly, are you invoking functionality through strings rather than function names?


How does the user enter or even know about function names? Strings are flexible and intuitive, I could have them give the program some numerical input but that could get confusing, or maybe have a strict menu system. But that none of that solves the problem of future flexibility.

Basicaly I'm looking for a more elegant way of doing this.
String SomeUserInput;cin >> SomeUserInput;if(SomeUserInput == "XYZfunction"){   //do somthing, or call some function}else if(SomeUserInput == "ABCfunction"){    //do somthing, or call some function}else if(SomeUserInput == "123function"){    //do somthing, or call some function}
I see. I thought by "user" you meant the user of the class (the programmer), as opposed to the "end user" (the user of the application as a whole).

If you really just want the user to type command names in ("party like it's 1979") and have the system execute them, just do the simplest possible thing, which in this case would be a std::map of function pointers or a long if-elseif-elseif chain. Either way you will have parallel code structures to maintain, but it shouldn't be too painful.

All of this, of course, would become much more pressing and difficult if you were passing in arguments on the commandline. You aren't, right?
Quote:Original post by Sneftel
I see. I thought by "user" you meant the user of the class (the programmer), as opposed to the "end user" (the user of the application as a whole).

If you really just want the user to type command names in ("party like it's 1979") and have the system execute them, just do the simplest possible thing, which in this case would be a std::map of function pointers or a long if-elseif-elseif chain. Either way you will have parallel code structures to maintain, but it shouldn't be too painful.

All of this, of course, would become much more pressing and difficult if you were passing in arguments on the command line. You aren't, right?
Yeah thats essentially right. However maintaining parallel code structures is exactly what I'm trying to avoid here. It seems I'm going about it the wrong way though.

This topic is closed to new replies.

Advertisement