Sign in to follow this  

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

This topic is 3572 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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
}

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
In a language such as C++, a minimal amount of this is unavoidable. It's already happening with header/source files, for instance. Don't sweat it.

Share this post


Link to post
Share on other sites

This topic is 3572 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this